1 /* Drop-down menus (GTK) */
2 /*
3  * This file is part of JED editor library source.
4  *
5  * You may always distribute this file under the terms the GNU General Public
6  * License.  See the file COPYING for more information.
7  */
8 
9 #define _BUILD_GTK_JED
10 
11 #include "config.h"
12 #include "jed-feat.h"
13 
14 #include <stdio.h>
15 #if JED_HAS_MENUS
16 
17 # include <gtk/gtk.h>
18 # include <gdk/gdkx.h>
19 # include <gdk/gdkkeysyms.h>
20 
21 # include <slang.h>
22 
23 # include "jdmacros.h"
24 
25 # include <string.h>
26 
27 # include "buffer.h"
28 # include "screen.h"
29 # include "misc.h"
30 # include "sysdep.h"
31 # include "cmds.h"
32 # include "menu.h"
33 # include "colors.h"
34 
35 #include "gtkjed.h"
36 
37 # define GTK_HAS_TOOLTIPS 0
38 
39 # if 0
40 static GHashTable    *menuArray;
41 
42 /*************************************************************************
43  *
44  * Datastructure to manage GtkMenus and Toolbars
45  *
46  * For Menus:
47  *
48  *   Settings for the Menubar:
49  *      parent     = NULL
50  *      menuItem   = menubar
51  *      subMenu    = NULL
52  *      path       = menu path
53  *
54  *   Settings for the submenu:
55  *      parent     = parent of type GtkJedMenuType *
56  *      menuItem   = current menu item (item in current menu)
57  *      subMenu    = the newly created submenu
58  *      path       = menu path
59  *
60  *   Settings for the menu item:
61  *      parent     = parent of type GtkJedMenuType *
62  *      menuItem   = current menu item (item in current menu)
63  *      subMenu    = NULL
64  *      path       = menu path
65  *
66  ************************************************************************/
67 
68 typedef struct GtkJedMenuTypeStruct
69 {
70    struct GtkJedMenuTypeStruct *parent;
71    GtkWidget                   *menuItem;
72    GtkWidget                   *subMenu;
73    char                        *path;
74 }
75 GtkJedMenuType;
76 
77 # endif
78 
79  /* static int         toolbarInputSelected = 0; */
80  /* static int         tbActive = 0; */
81 
82 extern void       gtkCreateTBCmd( char * );
83 extern void       gtkSetBufferMenuBarCmd( char * );
84 extern void       gtkInsertPopupMenuCmd( char *, char * );
85 extern void       gtkAppendTBCmd( char *, char * );
86 extern void       gtkInsertSeparatorCmd( char * );
87 extern void       gtkAppendSeparatorCmd( char * );
88 extern void       gtkMenuItemNew( char *, char *, int );
89 extern void       gtkMenuDeleteItemCmd( char * );
90 extern void       gtkMenuDeleteItemsCmd( char * );
91 extern void       gtkSetObjectAvailableCmd( char * );
92 
93 typedef struct _Menu_Node_Type
94 {
95    char *name;
96    int type;
97 # define MENU_NODE_FUN_SLANG	1
98       /* typedef struct {} Menu_SLang_Fun_Type; */
99 # define MENU_NODE_FUN_C		2
100       /* typedef struct {} Menu_C_Fun_Type; */
101 # define MENU_NODE_POPUP		3
102       /* typedef struct _Menu_Popup_Type {} Menu_Popup_Type; */
103 # define MENU_NODE_SEPARATOR	4
104       /* typedef struct _Menu_Node_Type {} Menu_Node_Type; */
105 # define MENU_NODE_MENUBAR	5
106       /* struct _Menu_Bar_Type {}; */
107 # define MENU_NODE_KEYSTRING	6
108       /* typedef struct {} Menu_Keystring_Fun_Type; */
109 # define MENU_NODE_TYPEDKEYS     7
110       /* typedef struct {} Menu_Keystring_Fun_Type; */
111 
112    unsigned int flags;
113 # define MENU_ACTIVE		     1
114 # define MENU_SELECTION		     2
115 # define MENU_ITEM_UNAVAILABLE	     4
116 # define MENU_POPUP_PREPARED	     8
117 # define JGTK_MENU_POPUP_PREPARED    16
118 
119    GtkWidget               *menuItem;
120    GtkWidget               *subMenu;
121 }
122 Menu_Node_Type;
123 
124 typedef struct _Menu_Popup_Type
125 {
126    char *name;
127    int type;			       /* =MENU_NODE_POPUP 3 */
128    unsigned int flags;
129 
130    GtkWidget               *menuItem;
131    GtkWidget               *subMenu;
132 
133    /* Private data */
134    /* These 5 must match Menu_Bar_Type */
135    Menu_Node_Type **subnodes;
136    unsigned int num_subnodes;
137    unsigned int max_subnodes;
138    struct _Menu_Popup_Type *parent;
139    unsigned int active_node;
140 
141    SLang_Name_Type *select_popup_callback;
142    SLang_Name_Type *tweak_popup_callback;
143 
144    int column;			       /* meaningful when active */
145    int row;
146    int max_row;
147    int max_col;
148    unsigned int min_width;
149    int visible_node_offset;
150 }
151 Menu_Popup_Type;
152 
153 struct _Menu_Bar_Type
154 {
155    char *name;
156    int type;			       /* =MENU_NODE_MENUBAR 5 */
157    unsigned int flags;
158 
159    GtkWidget               *menuItem;  /* gtk_menu_bar */
160    GtkWidget               *subMenu;   /* NULL */
161 
162    /* Private data */
163    /* These 5 must match Menu_Popup_Type */
164    Menu_Node_Type **subnodes;
165    unsigned int num_subnodes;
166    unsigned int max_subnodes;
167    struct _Menu_Popup_Type *parent;
168    unsigned int active_node;
169 
170    SLang_Name_Type *init_callback;
171    SLang_Name_Type *select_callback;   /* Void select_callback (name) */
172 
173    int *item_columns;	       /* locations of items on menu bar */
174    unsigned int num_refs;
175 
176 # define DEFAULT_MENU_PREFIX "F10 key ==> "
177    char *prefix_string;
178    struct _Menu_Bar_Type *next;
179 };
180 
181 typedef struct
182 {
183    char *name;
184    int type;              /* =MENU_NODE_FUN_SLANG 1 */
185    unsigned int flags;
186 
187    GtkWidget               *menuItem;
188    GtkWidget               *subMenu;
189 
190    SLang_Name_Type *slang_fun;
191    SLang_Any_Type *client_data;
192 }
193 Menu_SLang_Fun_Type;
194 
195 typedef struct
196 {
197    char *name;
198    int type;              /* =MENU_NODE_FUN_C 2 */
199    unsigned int flags;
200 
201    GtkWidget               *menuItem;
202    GtkWidget               *subMenu;
203 
204    int (*c_fun)(void);
205 }
206 Menu_C_Fun_Type;
207 
208 typedef struct
209 {
210    char *name;
211    int type;              /* =MENU_NODE_KEYSTRING 6, =Menu_NODE_TYPEDKEYS 7 */
212    unsigned int flags;
213 
214    GtkWidget               *menuItem;
215    GtkWidget               *subMenu;
216 
217    char *keystring;
218 }
219 Menu_Keystring_Fun_Type;
220 
221 /*******************************************************************************/
222 /***** creating Toolbars *******************************************************/
223 /*******************************************************************************/
224 
225 extern void       gtkCreateToolbarCmd( Menu_Bar_Type * );
226 extern void       gtkAddBufferToolbarCmd( char * );
227 static void       gtkToolbarStockItemNew( Menu_Popup_Type *, Menu_Node_Type *, char *, int );
228 static void       gtkToolbarItemNew( Menu_Popup_Type *, Menu_Node_Type *, char *, int );
229 static void       gtkToolbarAppendSeparatorCmd( Menu_Popup_Type *, Menu_Node_Type * );
230 static void       gtkToolbarInsertSeparatorCmd( Menu_Popup_Type *, Menu_Node_Type *, int );
231 
232 extern int        createKeyEvents( char * );
233 
234 static void       jGtkInsertBufferToolbarCmd( char *, int * );
235 
236 static int        jGtkSelectTB(void);
237 static int        jGtkExecTB(void);
238 
239 static gboolean   menuBarActivateCurrentCB( GtkWidget *,
240 					    GdkEvent  *,
241 					    gpointer  * );
242 
243 int        Jed_Menus_Active;
244 
245 static Menu_Bar_Type     *Global_Menu_Bar;
246 static Menu_Bar_Type     *Menu_Bar_Root;
247 static Menu_Bar_Type     *Active_Menu_Bar;
248 static Menu_Popup_Type   *Active_Popup;
249 
250 static void free_menu_node (Menu_Node_Type *);
251 static int select_menu_cmd (void);
252 
253 extern void              execTBCmd( char * );
254 static int               tbExecSlangFlag = 0;
255 static Menu_Node_Type   *actTBCmdNode;
256 static int               tbInputSelected = 0;
257 
258 static Menu_Popup_Type  *activeTopSubmenu = NULL;
259 
260 static void       jGtkCreateMenuBarCmd( Menu_Bar_Type * );
261 static void       jGtkInsertPopupMenuCmd( Menu_Popup_Type *, int );
262 static void       jGtkSimpleInsertPopupMenuCmd( Menu_Popup_Type *, int );
263 static void       jGtkMenuItemNew( Menu_Popup_Type *, Menu_Node_Type *, int );
264 static void       jGtkMenuKeystringItemNew( Menu_Popup_Type *, Menu_Node_Type *, int );
265 
266 static void       jGtkInsertSeparatorCmd( Menu_Popup_Type *, Menu_Node_Type *, int );
267 /* static void       jGtkAppendSeparatorCmd( Menu_Node_Type * ); */
268 
269 void       toolbarCallback( GtkWidget *, gpointer );
270 
271 # define TB_SEL_KEY_SEQ         "\033[TB"
272 # define TB_EXE_KEY_SEQ         "\033[TX"
273 
274 static char   tbExeKeySeq[] =  "\x1B[TX";  /* = TB_EXE_KEY_SEQ */
275 static int    tbExeKeyInx   =  0;
276 
277 /************************************
278 * free_menu_popup_subnodes
279 *
280 * debug print: "Menu: %x\n", m
281 *
282 ************************************/
283 
free_menu_popup_subnodes(Menu_Popup_Type * m)284 static void free_menu_popup_subnodes (Menu_Popup_Type *m)
285 {
286    Menu_Node_Type **l, **lmax;
287 
288    l = m->subnodes;
289    lmax = l + m->num_subnodes;
290 
291    while (l < lmax)
292      {
293 	free_menu_node (*l);
294 	l++;
295      }
296    SLfree ((char *) m->subnodes);
297 
298    m->subnodes = NULL;
299    m->num_subnodes = 0;
300    m->max_subnodes = 0;
301 }
302 
303 /************************************
304 * free_menu_popup_private_data
305 *
306 * debug print: "Menu: %x\n", m
307 *
308 ************************************/
309 
free_menu_popup_private_data(Menu_Popup_Type * m)310 static void free_menu_popup_private_data (Menu_Popup_Type *m)
311 {
312    free_menu_popup_subnodes (m);
313 # if SLANG_VERSION > 10400
314    SLang_free_function (m->select_popup_callback);
315    SLang_free_function (m->tweak_popup_callback);
316    m->select_popup_callback = NULL;
317    m->tweak_popup_callback = NULL;
318 # endif
319 }
320 
321 /************************************
322 * free_menu_bar_private_data
323 *
324 * debug print: "Menu: %x\n", m
325 *
326 ************************************/
327 
free_menu_bar_private_data(Menu_Bar_Type * m)328 static void free_menu_bar_private_data (Menu_Bar_Type *m)
329 {
330    Menu_Node_Type **l, **lmax;
331 
332    if (m == Active_Menu_Bar)
333      Active_Menu_Bar = NULL;
334 
335    if (m == Global_Menu_Bar)
336      Global_Menu_Bar = NULL;
337 
338    if (m == Menu_Bar_Root)
339      Menu_Bar_Root = m->next;
340    else
341      {
342 	Menu_Bar_Type *prev;
343 
344 	prev = Menu_Bar_Root;
345 	while (prev->next != m)
346 	  prev = prev->next;
347 
348 	prev->next = m->next;
349      }
350 
351    l = m->subnodes;
352    lmax = l + m->num_subnodes;
353 
354    while (l < lmax)
355      {
356 	free_menu_node (*l);
357 	l++;
358      }
359    SLfree ((char *) m->subnodes);
360    SLfree ((char *) m->item_columns);
361    SLang_free_slstring (m->prefix_string);
362 # if SLANG_VERSION > 10400
363    SLang_free_function (m->init_callback);
364    SLang_free_function (m->select_callback);
365 # endif
366 
367 }
368 
369 /************************************
370 * free_keystring_private_data
371 *
372 * debug print: "Menu Key String Function: %x\n", m
373 *
374 ************************************/
375 
free_keystring_private_data(Menu_Keystring_Fun_Type * m)376 static void free_keystring_private_data (Menu_Keystring_Fun_Type *m)
377 {
378    SLang_free_slstring (m->keystring);
379 }
380 
381 /************************************
382 * free_slangfun_private_data
383 *
384 * debug print: "Menu: %x\n", m
385 *
386 ************************************/
387 
free_slangfun_private_data(Menu_SLang_Fun_Type * m)388 static void free_slangfun_private_data (Menu_SLang_Fun_Type *m)
389 {
390    if (m->client_data != NULL)
391      SLang_free_anytype (m->client_data);
392 # if SLANG_VERSION > 10400
393    SLang_free_function (m->slang_fun);
394 # endif
395 }
396 
397 /************************************
398 * free_menu_node
399 *
400 * debug print: "Menu: %x, Name: |%s|\n", m, m->name
401 *
402 ************************************/
403 
free_menu_node(Menu_Node_Type * m)404 static void free_menu_node (Menu_Node_Type *m)
405 {
406    Menu_Bar_Type *b;
407 
408    if (m == NULL)
409      return;
410 
411    switch (m->type)
412      {
413       case MENU_NODE_SEPARATOR:
414       case MENU_NODE_FUN_C:
415 	break;
416 
417       case MENU_NODE_FUN_SLANG:
418 	free_slangfun_private_data ((Menu_SLang_Fun_Type *) m);
419 	break;
420 
421       case MENU_NODE_KEYSTRING:
422 	free_keystring_private_data ((Menu_Keystring_Fun_Type *) m);
423 	break;
424 
425       case MENU_NODE_MENUBAR:
426 	b = (Menu_Bar_Type *)m;
427 	if (b->num_refs > 1)
428 	  {
429 	     b->num_refs -= 1;
430 	     return;
431 	  }
432 	free_menu_bar_private_data ((Menu_Bar_Type *) m);
433 	break;
434 
435       case MENU_NODE_POPUP:
436 	free_menu_popup_private_data ((Menu_Popup_Type *) m);
437 	break;
438      }
439 
440    /* Dbp1( "m->menuItem: %x\n", m->menuItem ); */
441 
442    if ( m->menuItem ) gtk_widget_destroy( m->menuItem );
443 
444    /* Dbp1( "m->subMenu: %x\n", m->subMenu ); */
445 
446    if ( m->subMenu ) gtk_widget_destroy( m->subMenu );
447 
448    SLang_free_slstring (m->name);
449    SLfree ((char *) m);
450 }
451 
452 /************************************
453 * create_menu_node
454 *
455 * debug print: "Name: %s, Node type: %d, Size of node: %d\n", name, node_type, sizeof_node
456 *
457 ************************************/
458 
create_menu_node(char * name,int node_type,unsigned int sizeof_node)459 static Menu_Node_Type *create_menu_node (char *name, int node_type,
460 					 unsigned int sizeof_node)
461 {
462    Menu_Node_Type *m;
463 
464    m = (Menu_Node_Type *) jed_malloc0 (sizeof_node);
465    if (m == NULL)
466      return NULL;
467 
468    m->type = node_type;
469    m->menuItem = NULL;
470    m->subMenu = NULL;
471    /* m->flags = 0; */
472 
473    if (NULL == (m->name = SLang_create_slstring (name)))
474      {
475 	SLfree ((char *)m);
476 	return NULL;
477      }
478 
479    return m;
480 }
481 
482 /************************************
483 * create_menu_popup
484 *
485 * debug print: "Name: %s, Num items: %d\n", name, num_items
486 *
487 ************************************/
488 
489 static Menu_Popup_Type *
create_menu_popup(char * name,unsigned int num_items)490 create_menu_popup (char *name, unsigned int num_items)
491 {
492    Menu_Popup_Type *m;
493 
494    m = (Menu_Popup_Type *) create_menu_node (name, MENU_NODE_POPUP, sizeof (Menu_Popup_Type));
495    if (m == NULL)
496      return NULL;
497 
498    if (num_items == 0)
499      num_items = 5;
500 
501    if (NULL == (m->subnodes = (Menu_Node_Type **)SLmalloc (num_items * sizeof (Menu_Node_Type *))))
502      {
503 	free_menu_node ((Menu_Node_Type *) m);
504 	return NULL;
505      }
506    m->max_subnodes = num_items;
507    return m;
508 }
509 
510 /************************************
511 * create_menu_bar
512 *
513 * debug print: "Name: %s, Num items: %d\n", name, num_items
514 *
515 ************************************/
516 
517 static Menu_Bar_Type *
create_menu_bar(char * name,unsigned int num_items)518 create_menu_bar( char *name,
519 		 unsigned int num_items )
520 {
521    Menu_Bar_Type *m;
522    char *prefix;
523 
524    m = ( Menu_Bar_Type * ) create_menu_node( name, MENU_NODE_MENUBAR, sizeof( Menu_Bar_Type ) );
525    if ( m == NULL )
526      return NULL;
527 
528    if ( num_items == 0 )
529      num_items = 5;
530 
531    if ((NULL == (m->subnodes = (Menu_Node_Type **)SLmalloc (num_items * sizeof (Menu_Node_Type *))))
532        || (NULL == (m->item_columns = (int *)jed_malloc0 (num_items * sizeof (int)))))
533      {
534 	free_menu_node ((Menu_Node_Type *) m);
535 	return NULL;
536      }
537 
538    m->max_subnodes = num_items;
539 
540    if (Menu_Bar_Root != NULL)
541      m->next = Menu_Bar_Root;
542    Menu_Bar_Root = m;
543 
544    m->num_refs = 1;
545 
546    prefix = DEFAULT_MENU_PREFIX;
547    if ((Global_Menu_Bar != NULL)
548        && (Global_Menu_Bar->prefix_string != NULL))
549      prefix = Global_Menu_Bar->prefix_string;
550 
551    prefix = SLang_create_slstring (prefix);
552    if (prefix == NULL)
553      {
554 	jed_delete_menu_bar (m);
555 	return NULL;
556      }
557    m->prefix_string = prefix;
558 
559    return m;
560 }
561 
562 /************************************
563 * jed_delete_menu_bar
564 *
565 * debug print: "Menu Bar Type: %x\n", m
566 *
567 ************************************/
568 
569 void
jed_delete_menu_bar(Menu_Bar_Type * m)570 jed_delete_menu_bar (Menu_Bar_Type *m)
571 {
572    if ( m == NULL )
573      return;
574 
575    free_menu_node ((Menu_Node_Type *)m);
576 }
577 
578 /************************************
579 * menu_name_eqs
580 *
581 * debug print: "A: |%s|, B: |%s|, bMax: |%s|\n", a, b, bmax
582 *
583 ************************************/
584 
585 static int
menu_name_eqs(char * a,char * b,char * bmax)586 menu_name_eqs( char *a, char *b, char *bmax )
587 {
588    while (*a)
589      {
590 	if ( ( b == bmax )
591 	     || ( *a != *b ) )
592 	  return 0;
593 	a++;
594 	b++;
595      }
596 
597    return( b == bmax );
598 }
599 
600 /************************************
601 * menu_find_menu_bar
602 *
603 * debug print: "Name: |%s|, do error: %d\n", name, do_error
604 *
605 ************************************/
606 
menu_find_menu_bar(char * name,int do_error)607 static Menu_Bar_Type *menu_find_menu_bar (char *name, int do_error)
608 {
609    Menu_Bar_Type *b;
610    char *name_max;
611 
612    name_max = strchr (name, '.');
613    if (name_max == NULL)
614      name_max = name + strlen (name);
615 
616    b = Menu_Bar_Root;
617    while (b != NULL)
618      {
619 	if (menu_name_eqs (b->name, name, name_max))
620 	  return b;
621 
622 	b = b->next;
623      }
624 
625    if (do_error)
626      SLang_verror (SL_INTRINSIC_ERROR,
627 		   "Unable to a find menu bar called %s",
628 		   name);
629    return NULL;
630 }
631 
632 /************************************
633 * find_subnode
634 *
635 * debug print: "Menu popup type: %x, Name: |%s|\n", m, name
636 *
637 ************************************/
638 
find_subnode(Menu_Popup_Type * m,char * name)639 static Menu_Node_Type *find_subnode (Menu_Popup_Type *m, char *name)
640 {
641    Menu_Node_Type **l, **lmax;
642 
643    if (m == NULL)
644      return NULL;
645 
646    l = m->subnodes;
647    lmax = l + m->num_subnodes;
648 
649    while (l < lmax)
650      {
651 	if (0 == strcmp (name, (*l)->name))
652 	  return *l;
653 
654 	l++;
655      }
656    return NULL;
657 }
658 
659 /************************************
660 * check_subnode_space
661 *
662 * debug print: "Menu: %x, Dn: %d\n", m, dn
663 *
664 ************************************/
665 
check_subnode_space(Menu_Popup_Type * m,unsigned int dn)666 static int check_subnode_space (Menu_Popup_Type *m, unsigned int dn)
667 {
668    Menu_Node_Type **subnodes;
669    unsigned int num;
670 
671    if (m->num_subnodes + dn <= m->max_subnodes)
672      return 0;
673 
674    num = m->max_subnodes + dn;
675 
676    subnodes = (Menu_Node_Type **)SLrealloc ((char *)m->subnodes, num * sizeof (Menu_Node_Type *));
677    if (subnodes == NULL)
678      return -1;
679    m->subnodes = subnodes;
680 
681    if (m->type == MENU_NODE_MENUBAR)
682      {
683 	Menu_Bar_Type *b = (Menu_Bar_Type *)m;
684 	int *item_columns;
685 	unsigned int i;
686 
687 	item_columns = (int *)SLrealloc ((char *)b->item_columns, num * sizeof(int));
688 	if (item_columns == NULL)
689 	  return -1;
690 
691 	for (i = m->max_subnodes; i < num; i++)
692 	  item_columns [i] = 0;
693 	b->item_columns = item_columns;
694      }
695 
696    m->max_subnodes = num;
697    return 0;
698 }
699 
700 /************************************
701 * insert_node_to_popup
702 * This function assumes that there is enough space to insert one item *
703 *
704 * debug print: "Menu popup type: %x, menu node type: %x, where: %d\n", p, m, where
705 *
706 ************************************/
707 
708 static void
insert_node_to_popup(Menu_Popup_Type * p,Menu_Node_Type * m,unsigned int where)709 insert_node_to_popup( Menu_Popup_Type *p,
710 		      Menu_Node_Type *m,
711 		      unsigned int where )
712 {
713    unsigned int len;
714    unsigned int n;
715 
716    n = p->num_subnodes;
717 
718    if (where > n)
719      where = n;
720 
721    while (n > where)
722      {
723 	p->subnodes[n] = p->subnodes[n-1];
724 	n--;
725      }
726    p->subnodes[where]  = m;
727    p->num_subnodes += 1;
728 
729    /* p could be a menu-bar */
730 
731    if (p->type != MENU_NODE_POPUP)
732      return;
733 
734    len = strlen( m->name );
735    if ( len > p->min_width )
736      p->min_width = len;
737 }
738 
739 /************************************
740 * insert_popup_menu
741 *
742 * debug print: "Menu popup type: %x, Name: |%s|, where: %d\n", m, name, where
743 *
744 ************************************/
745 
insert_popup_menu(Menu_Popup_Type * m,char * name,int where)746 static Menu_Popup_Type *insert_popup_menu (Menu_Popup_Type *m, char *name, int where)
747 {
748    Menu_Popup_Type *p;
749 
750    if (NULL != (p = (Menu_Popup_Type *)find_subnode (m, name)))
751      return p;
752 
753    if (-1 == check_subnode_space (m, 1))
754      return NULL;
755 
756    p = create_menu_popup (name, 5);
757    if (p == NULL)
758      return NULL;
759 
760    p->parent = m;
761 
762    insert_node_to_popup (m, (Menu_Node_Type *)p, where);
763    return p;
764 }
765 
766 /************************************
767 * append_popup_menu
768 *
769 * debug print: "Menu: %x, Name: |%s|\n", m, name
770 *
771 ************************************/
772 
append_popup_menu(Menu_Popup_Type * m,char * name)773 static Menu_Popup_Type *append_popup_menu (Menu_Popup_Type *m, char *name)
774 {
775    return insert_popup_menu (m, name, m->num_subnodes);
776 }
777 
778 /************************************
779 * insert_separator
780 *
781 * debug print: "Menu: %x, where: %d\n", m, where
782 *
783 ************************************/
784 
insert_separator(Menu_Popup_Type * m,int where)785 static Menu_Node_Type *insert_separator (Menu_Popup_Type *m, int where)
786 {
787    Menu_Node_Type *l;
788 
789    if (-1 == check_subnode_space (m, 1))
790      return NULL;
791 
792    l = create_menu_node ("", MENU_NODE_SEPARATOR, sizeof (Menu_Node_Type));
793    if (l == NULL)
794      return NULL;
795 
796    insert_node_to_popup (m, l, where);
797 
798    return l;
799 }
800 
801 /************************************
802 * append_separator
803 *
804 * debug print: "Menu: %x\n", m
805 *
806 ************************************/
807 
append_separator(Menu_Popup_Type * m)808 static Menu_Node_Type *append_separator (Menu_Popup_Type *m)
809 {
810    return insert_separator (m, m->num_subnodes);
811 }
812 
813 /************************************
814 * insert_slang_fun_item
815 *
816 * debug print: "Menu: %x, Name: |%s|, Nt: %x, Cd: %x, Where: %d\n", m, name, nt, cd, where
817 *
818 ************************************/
819 
820 static Menu_SLang_Fun_Type *
insert_slang_fun_item(Menu_Popup_Type * m,char * name,SLang_Name_Type * nt,SLang_Any_Type * cd,int where)821 insert_slang_fun_item( Menu_Popup_Type *m, char *name,
822 		       SLang_Name_Type *nt, SLang_Any_Type *cd,
823 		       int where)
824 {
825    Menu_SLang_Fun_Type *l;
826 
827    if (NULL != (l = (Menu_SLang_Fun_Type *)find_subnode (m, name)))
828      {
829 	if (l->type != MENU_NODE_FUN_SLANG)
830 	  return NULL;
831 
832 	free_slangfun_private_data (l);
833 	l->slang_fun = nt;
834 	l->client_data = cd;
835 
836 	return l;
837      }
838 
839    if (-1 == check_subnode_space (m, 1))
840      return NULL;
841 
842    l = (Menu_SLang_Fun_Type *)
843      create_menu_node (name, MENU_NODE_FUN_SLANG, sizeof (Menu_SLang_Fun_Type));
844 
845    if (l == NULL)
846      return NULL;
847 
848    l->slang_fun = nt;
849    l->client_data = cd;
850 
851    insert_node_to_popup (m, (Menu_Node_Type *)l, where);
852    return l;
853 }
854 
855 /************************************
856 * append_slang_fun_item
857 *
858 * debug print: "Menu: %x, Name: |%s|, Nt: %x, Cd: %x\n", m, name, nt, cd
859 *
860 ************************************/
861 
append_slang_fun_item(Menu_Popup_Type * m,char * name,SLang_Name_Type * nt,SLang_Any_Type * cd)862 static Menu_SLang_Fun_Type *append_slang_fun_item (Menu_Popup_Type *m, char *name,
863 						   SLang_Name_Type *nt, SLang_Any_Type *cd)
864 {
865    return insert_slang_fun_item (m, name, nt, cd, m->num_subnodes);
866 }
867 
868 /************************************
869 * insert_keystring_item
870 *
871 * debug print: "Menu: %x, Name: |%s|, k: |%s|, Where: %d\n", m, name, k, where
872 *
873 ************************************/
874 
875 static Menu_Keystring_Fun_Type *
insert_keystring_item(Menu_Popup_Type * m,char * name,char * k,int where)876 insert_keystring_item( Menu_Popup_Type *m, char *name,
877 		       char *k, int where )
878 {
879    Menu_Keystring_Fun_Type *l;
880 
881    if (NULL != (l = (Menu_Keystring_Fun_Type *)find_subnode (m, name)))
882      {
883 	if (l->type != MENU_NODE_KEYSTRING)
884 	  return NULL;
885 
886 	if (NULL == (k = SLang_create_slstring (k)))
887 	  return NULL;
888 
889 	free_keystring_private_data (l);
890 	l->keystring = k;
891 	return l;
892      }
893 
894    if (-1 == check_subnode_space (m, 1))
895      return NULL;
896 
897    l = (Menu_Keystring_Fun_Type *)
898      create_menu_node (name, MENU_NODE_KEYSTRING, sizeof (Menu_Keystring_Fun_Type));
899 
900    if (l == NULL)
901      return NULL;
902 
903    if (NULL == (l->keystring = SLang_create_slstring (k)))
904      {
905 	free_menu_node ((Menu_Node_Type *) l);
906 	return NULL;
907      }
908 
909    /* Dbp( "l->keystring: |%s|\n", l->keystring ); */
910 
911    insert_node_to_popup (m, (Menu_Node_Type *)l, where);
912    return l;
913 }
914 
915 /************************************
916 * append_keystring_item
917 *
918 * debug print: "Menu popup type: %x, Name: |%s|, k: |%s|\n", m, name, k
919 *
920 ************************************/
921 
922 static Menu_Keystring_Fun_Type *
append_keystring_item(Menu_Popup_Type * m,char * name,char * k)923 append_keystring_item (Menu_Popup_Type *m, char *name, char *k)
924 {
925    return insert_keystring_item (m, name, k, m->num_subnodes);
926 }
927 
928 /************************************
929 * insertSpecCmdItem
930 *********************
931 * Currently no use of specCmd. Maybe for future use
932 *
933 * debug print: "Menu: %x, Name: %s, SpecCmd: %s, KeySeq: %s, Where: %d", m, name, specCmd, keySeq, where
934 *
935 ************************************/
936 
937 static Menu_Keystring_Fun_Type *
insertSpecCmdItem(Menu_Popup_Type * m,char * name,char * specCmd,char * keySeq,int where)938 insertSpecCmdItem( Menu_Popup_Type *m, char *name,
939 		   char *specCmd, char *keySeq, int where )
940 {
941    Menu_Keystring_Fun_Type *l;
942    char *buf;
943    char *k;
944 
945    /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
946 
947    if (NULL != (l = (Menu_Keystring_Fun_Type *)find_subnode (m, name)))
948      {
949       /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
950 	if (l->type != MENU_NODE_TYPEDKEYS)
951 	  return NULL;
952       /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
953 
954 	l->keystring = SLang_create_slstring( keySeq );
955 
956 # if 0
957 	Dbp( "buf: |%s|\n", buf );
958 
959       /* printf( "File: %s, Line: %d: insertSpecCmdItem: Length: %d\n", __FILE__, __LINE__, *buf ); */
960 
961 	if ( NULL == ( k = SLmalloc( sizeof( ( *buf ) + 1 ) ) ) )
962 	  return NULL;
963 
964 	strncpy( k, buf, *buf );
965 	k[*buf] = '\0';
966 
967       /* if (NULL == (k = SLang_create_slstring (k))) */
968       /*   Return NULL; */
969       /* free_keystring_private_data (l); */
970       /* */
971 # endif
972 
973 	l->keystring = k;
974 	return l;
975      }
976 
977    /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
978 
979    if (-1 == check_subnode_space (m, 1))
980      return NULL;
981    /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
982 
983    l = (Menu_Keystring_Fun_Type *)
984      create_menu_node (name, MENU_NODE_TYPEDKEYS, sizeof (Menu_Keystring_Fun_Type));
985 
986    /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
987 
988    if (l == NULL)
989      return NULL;
990 
991    /* printf( "File: %s, Line: %d: insertSpecCmdItem\n", __FILE__, __LINE__ ); */
992 
993    buf = SLang_process_keystring( keySeq );
994    /* printf( "File: %s, Line: %d: insertSpecCmdItem: Length: %d 1: |%x| 2: |%c|\n", __FILE__, __LINE__, *buf, *buf, buf[1] ); */
995 
996    /* if (NULL == (l->keystring = SLang_create_slstring (k))) */
997    if ( NULL == ( k = SLmalloc( sizeof( ( *buf ) + 1 ) ) ) )
998      {
999 	free_menu_node ((Menu_Node_Type *) l);
1000 	return NULL;
1001      }
1002 
1003    strncpy( k, buf, *buf );
1004    k[(unsigned char)*buf] = '\0';
1005 
1006    /* printf( "File: %s, Line: %d: insertSpecCmdItem: Node: %x, String: %x, 1: |%x| 2: |%x| 3: |%x|\n", */
1007    /*	   __FILE__, __LINE__, l, k, *k, k[1], k[2] ); */
1008 
1009    l->keystring = k;
1010 
1011    insert_node_to_popup (m, (Menu_Node_Type *)l, where);
1012    return l;
1013 
1014    /* Return( NULL ); */
1015 }
1016 
1017 /************************************
1018 * get_selected_menu_item
1019 *
1020 * debug print: "Menu: %x\n", p
1021 *
1022 ************************************/
1023 
get_selected_menu_item(Menu_Popup_Type * p)1024 static Menu_Node_Type *get_selected_menu_item (Menu_Popup_Type *p)
1025 {
1026    Menu_Node_Type *m;
1027 
1028    if (p == NULL)
1029      return NULL;
1030 
1031    /* Db; */
1032 
1033    if (p->num_subnodes <= p->active_node)
1034      {
1035         /* Db; */
1036 	p->active_node = 0;
1037 	return NULL;
1038      }
1039 
1040    /* Db; */
1041    m = p->subnodes[p->active_node];
1042 
1043    if (m->flags & MENU_ITEM_UNAVAILABLE)
1044      {
1045       /* Db; */
1046 	p->active_node = 0;
1047 	return NULL;
1048      }
1049 
1050    /* Make sure this is selected. */
1051    m->flags |= MENU_SELECTION;
1052    /* Db; */
1053    return m;
1054 }
1055 
1056 /************************************
1057 * unselect_active_node
1058 *
1059 * debug print: "Menu: %x\n", b
1060 *
1061 ************************************/
1062 
unselect_active_node(Menu_Popup_Type * b)1063 static int unselect_active_node (Menu_Popup_Type *b)
1064 {
1065    Menu_Node_Type *m;
1066 
1067    if (NULL == (m = get_selected_menu_item (b)))
1068      return -1;
1069 
1070    m->flags &= ~(MENU_SELECTION|MENU_ACTIVE);
1071    return 0;
1072 }
1073 
1074 /************************************
1075 * select_next_active_node
1076 *
1077 * debug print: "Menu: %x, active: %d, flags: %d\n", b, active_node, flags
1078 *
1079 ************************************/
1080 
select_next_active_node(Menu_Popup_Type * b,unsigned int active_node,unsigned int flags)1081 static int select_next_active_node (Menu_Popup_Type *b, unsigned int active_node,
1082 				    unsigned int flags)
1083 {
1084    int wrapped;
1085    unsigned int num_subnodes;
1086 
1087    if (b == NULL)
1088      return -1;
1089 
1090    num_subnodes = b->num_subnodes;
1091 
1092    if (num_subnodes == 0)
1093      {
1094 	b->active_node = 0;
1095 	return -1;
1096      }
1097 
1098    unselect_active_node (b);
1099 
1100    wrapped = 0;
1101 
1102    while (1)
1103      {
1104 	Menu_Node_Type *node;
1105 
1106 	active_node++;
1107 	if (active_node >= num_subnodes)
1108 	  {
1109 	     active_node = 0;
1110 	     if (wrapped)
1111 	       return -1;
1112 
1113 	     wrapped = 1;
1114 	  }
1115 
1116 	node = b->subnodes[active_node];
1117 	if ((node->type != MENU_NODE_SEPARATOR)
1118 	    && (0 == (node->flags & MENU_ITEM_UNAVAILABLE)))
1119 	  {
1120 	     node->flags |= MENU_SELECTION|flags;
1121 	     break;
1122 	  }
1123      }
1124 
1125    b->active_node = active_node;
1126    return 0;
1127 }
1128 
1129 /************************************
1130 * select_prev_active_node
1131 *
1132 * debug print: "Menu %x, Active Node: %d, flags %d\n", b, active_node, flags
1133 *
1134 ************************************/
1135 
select_prev_active_node(Menu_Popup_Type * b,unsigned int active_node,unsigned int flags)1136 static int select_prev_active_node (Menu_Popup_Type *b, unsigned int active_node,
1137 				    unsigned int flags)
1138 {
1139    int wrapped;
1140    unsigned int num_subnodes;
1141 
1142    if (b == NULL)
1143      return -1;
1144 
1145    num_subnodes = b->num_subnodes;
1146 
1147    if (num_subnodes == 0)
1148      {
1149 	b->active_node = 0;
1150 	return -1;
1151      }
1152 
1153    unselect_active_node (b);
1154 
1155    wrapped = 0;
1156 
1157    while (1)
1158      {
1159 	Menu_Node_Type *node;
1160 
1161 	if (active_node == 0)
1162 	  {
1163 	     active_node = num_subnodes;
1164 	     if (wrapped)
1165 	       return -1;
1166 
1167 	     wrapped = 1;
1168 	  }
1169 	active_node--;
1170 
1171 	node = b->subnodes[active_node];
1172 	if ((node->type != MENU_NODE_SEPARATOR)
1173 	    && (0 == (node->flags & MENU_ITEM_UNAVAILABLE)))
1174 	  {
1175 	     node->flags |= MENU_SELECTION|flags;
1176 	     break;
1177 	  }
1178      }
1179 
1180    b->active_node = active_node;
1181    return 0;
1182 }
1183 
1184 /************************************
1185 * set_node_selection
1186 *
1187 * debug print: "Menu %x, Menu-node: %x\n", p, m
1188 *
1189 ************************************/
1190 
set_node_selection(Menu_Popup_Type * p,Menu_Node_Type * m)1191 static int set_node_selection (Menu_Popup_Type *p, Menu_Node_Type *m)
1192 {
1193    unsigned int i, imax;
1194    Menu_Node_Type **subnodes;
1195 
1196    if ((p == NULL) || (m == NULL)
1197        || (m->type == MENU_NODE_SEPARATOR)
1198        || (m->flags & MENU_ITEM_UNAVAILABLE))
1199      return -1;
1200 
1201    subnodes = p->subnodes;
1202    imax = p->num_subnodes;
1203    for (i = 0; i < imax; i++)
1204      {
1205 	if (subnodes[i] == m)
1206 	  {
1207 	     unselect_active_node (p);
1208 	     p->active_node = i;
1209 	     m->flags |= MENU_SELECTION;
1210 	     return 0;
1211 	  }
1212      }
1213    return -1;
1214 }
1215 
1216 /************************************
1217 * get_active_node_flags
1218 *
1219 * debug print: "Menu: %x\n", p
1220 *
1221 ************************************/
1222 
get_active_node_flags(Menu_Popup_Type * p)1223 static unsigned int get_active_node_flags (Menu_Popup_Type *p)
1224 {
1225    Menu_Node_Type *m;
1226 
1227    m = get_selected_menu_item (p);
1228    if (m == NULL)
1229      return 0;
1230 
1231    return m->flags;
1232 }
1233 
1234 /************************************
1235 * menu_delete_node
1236 *
1237 * debug print: "Menu: %x, Menu node: %x\n", p, m
1238 *
1239 ************************************/
1240 
menu_delete_node(Menu_Popup_Type * p,Menu_Node_Type * m)1241 static int menu_delete_node (Menu_Popup_Type *p, Menu_Node_Type *m)
1242 {
1243    unsigned int i, imax;
1244 
1245    if ((p == NULL) || (m == NULL))
1246      return -1;
1247 
1248    imax = p->num_subnodes;
1249    for (i = 0; i < imax; i++)
1250      {
1251 	if (p->subnodes[i] != m)
1252 	  continue;
1253 
1254 	if (i == p->active_node)
1255 	  p->active_node = 0;
1256 
1257 	while (++i < imax)
1258 	  p->subnodes[i-1] = p->subnodes[i];
1259 
1260 	p->num_subnodes -= 1;
1261 
1262 	(void) unselect_active_node (p);
1263 	free_menu_node (m);
1264 	return 0;
1265      }
1266    return -1;
1267 }
1268 
1269 /************************************
1270 * menu_delete_nodes
1271 *
1272 * debug print: "Menu: %x\n", p
1273 *
1274 ************************************/
1275 
menu_delete_nodes(Menu_Popup_Type * p)1276 static int menu_delete_nodes (Menu_Popup_Type *p)
1277 {
1278    unsigned int i, imax;
1279 
1280    if (p == NULL)
1281      return -1;
1282 
1283    imax = p->num_subnodes;
1284    for (i = 0; i < imax; i++)
1285      free_menu_node (p->subnodes[i]);
1286 
1287    p->num_subnodes = 0;
1288    p->active_node = 0;
1289    return 0;
1290 }
1291 
1292 /************************************
1293 * copy_menu
1294 *
1295 * debug print: "Menu dest: %x, Menu node src: %x\n", dest, src
1296 *
1297 ************************************/
1298 
copy_menu(Menu_Popup_Type * dest,Menu_Node_Type * src)1299 static int copy_menu (Menu_Popup_Type *dest, Menu_Node_Type *src)
1300 {
1301    Menu_Node_Type **l, **lmax;
1302    Menu_Popup_Type *p;
1303    Menu_Node_Type *m;
1304    SLang_Any_Type *any;
1305    Menu_SLang_Fun_Type *sl;
1306 
1307    if (src == (Menu_Node_Type *)dest)
1308      {
1309 	SLang_verror (SL_INTRINSIC_ERROR,
1310 		      "Unable to copy a menu onto itself");
1311 	return -1;
1312      }
1313 
1314    switch (src->type)
1315      {
1316       case MENU_NODE_POPUP:
1317 	p = (Menu_Popup_Type *) src;
1318 	l = p->subnodes;
1319 	lmax = l + p->num_subnodes;
1320 
1321 	p = append_popup_menu (dest, src->name);
1322 	if (p == NULL)
1323 	  return -1;
1324 
1325 	while (l < lmax)
1326 	  {
1327 	     if (-1 == copy_menu (p, *l))
1328 	       {
1329 		  menu_delete_node (dest, (Menu_Node_Type *)p);
1330 		  return -1;
1331 	       }
1332 	     l++;
1333 	  }
1334 	m = (Menu_Node_Type *)p;
1335 	break;
1336 
1337       case MENU_NODE_SEPARATOR:
1338 	m = append_separator (dest);
1339 	break;
1340 
1341       case MENU_NODE_FUN_SLANG:
1342 	sl = (Menu_SLang_Fun_Type *) src;
1343 	/* Need a s-lang fun for this !!! */
1344 	if ((-1 == SLang_push_anytype (sl->client_data))
1345 	    || (-1 == SLang_pop_anytype (&any)))
1346 	  return -1;
1347 
1348 	m = (Menu_Node_Type *) append_slang_fun_item (dest, sl->name,
1349 						      sl->slang_fun, any);
1350 	if (m == NULL)
1351 	  SLang_free_anytype (any);
1352 	break;
1353 
1354       case MENU_NODE_KEYSTRING:
1355 	m = (Menu_Node_Type *) append_keystring_item (dest, src->name, ((Menu_Keystring_Fun_Type *)src)->keystring);
1356 	break;
1357 
1358       case MENU_NODE_MENUBAR:
1359 	SLang_verror (SL_INTRINSIC_ERROR, "Unable to copy a menu-bar");
1360 	return -1;
1361 
1362       case MENU_NODE_FUN_C:
1363       default:
1364 	  SLang_verror (SL_APPLICATION_ERROR,
1365 			"Menu Type %d not supported", src->type);
1366 	return -1;
1367      }
1368 
1369    if (m == NULL)
1370      return -1;
1371 
1372    m->flags = src->flags;
1373    return 0;
1374 }
1375 
1376 /************************************
1377 * gtkCopyMenu
1378 *
1379 * debug print: "Menu dest: %x: |%s|, Menu node src: %x: |%s|\n", dest, dest->name, src, src->name
1380 *
1381 ************************************/
1382 
1383 static int
gtkCopyMenu(Menu_Popup_Type * dest,Menu_Node_Type * src)1384 gtkCopyMenu( Menu_Popup_Type *dest, Menu_Node_Type *src )
1385 {
1386    int numItems;
1387    Menu_Node_Type **l, **lmax;
1388    Menu_Popup_Type *p;
1389    Menu_Node_Type *m;
1390    SLang_Any_Type *any;
1391    Menu_SLang_Fun_Type *sl;
1392 
1393    if (src == (Menu_Node_Type *)dest)
1394      {
1395 	SLang_verror (SL_INTRINSIC_ERROR,
1396 		      "Unable to copy a menu onto itself");
1397 	return -1;
1398      }
1399 
1400    switch (src->type)
1401      {
1402       case MENU_NODE_POPUP:
1403         /* Db; */
1404 	p = (Menu_Popup_Type *) src;
1405 	l = p->subnodes;
1406 	lmax = l + p->num_subnodes;
1407 
1408         numItems = dest->num_subnodes;
1409 
1410 	p = append_popup_menu (dest, src->name);
1411 
1412 	if (p == NULL)
1413 	  return -1;
1414 
1415         jGtkInsertPopupMenuCmd( p, numItems );
1416 
1417 	while (l < lmax)
1418 	  {
1419 	     /* if (-1 == copy_menu (p, *l)) */
1420 	     if (-1 == gtkCopyMenu (p, *l))
1421 	       {
1422 		  menu_delete_node (dest, (Menu_Node_Type *)p);
1423 		  return -1;
1424 	       }
1425 	     l++;
1426 	  }
1427 	m = (Menu_Node_Type *)p;
1428 	break;
1429 
1430       case MENU_NODE_SEPARATOR:
1431         /* Db; */
1432 	m = append_separator (dest);
1433         if ( m )
1434 	  jGtkInsertSeparatorCmd( dest, m, dest->num_subnodes - 1 );
1435 	break;
1436 
1437       case MENU_NODE_FUN_SLANG:
1438         /* Db; */
1439 	sl = (Menu_SLang_Fun_Type *) src;
1440 	/* Need a s-lang fun for this !!! */
1441 	if ((-1 == SLang_push_anytype (sl->client_data))
1442 	    || (-1 == SLang_pop_anytype (&any)))
1443 	  return -1;
1444 
1445 	m = (Menu_Node_Type *) append_slang_fun_item (dest, sl->name,
1446 						      sl->slang_fun, any);
1447         /* jGtkMenuItemNew( dest, m, dest->num_subnodes - 1 ); */
1448 	if (m == NULL)
1449 	  SLang_free_anytype (any);
1450         else
1451           jGtkMenuItemNew( dest, m, dest->num_subnodes - 1 );
1452 	break;
1453 
1454       case MENU_NODE_KEYSTRING:
1455         /* Db; */
1456 	m = (Menu_Node_Type *) append_keystring_item (dest, src->name, ((Menu_Keystring_Fun_Type *)src)->keystring);
1457         if ( m )
1458 	  jGtkMenuKeystringItemNew( dest, m, dest->num_subnodes - 1 );
1459 	break;
1460 
1461       case MENU_NODE_TYPEDKEYS:
1462         /* Db; */
1463 	SLang_verror (SL_INTRINSIC_ERROR, "Copy of Typed keys should not occur! Internal error.");
1464         return -1;
1465 
1466       case MENU_NODE_MENUBAR:
1467         /* Db; */
1468 	SLang_verror (SL_INTRINSIC_ERROR, "Unable to copy a menu-bar");
1469 	return -1;
1470 
1471       case MENU_NODE_FUN_C:
1472       default:
1473         /* Db; */
1474 	  SLang_verror (SL_APPLICATION_ERROR,
1475 			"Menu Type %d not supported", src->type);
1476 	return -1;
1477      }
1478 
1479    if (m == NULL)
1480      return -1;
1481 
1482    m->flags = src->flags;
1483    return 0;
1484 }
1485 
1486 /*
1487  *  SLsmg MenuBar interface
1488  */
1489 
1490 /************************************
1491 * simulate_hline
1492 *
1493 * debug print: "Line: %d\n", n
1494 *
1495 ************************************/
1496 
simulate_hline(unsigned int n)1497 static void simulate_hline (unsigned int n)
1498 {
1499    while (n--)
1500      SLsmg_write_string ("-");
1501 }
1502 
1503 /************************************
1504 * simulate_box
1505 *
1506 * debug print: "r: %d, c: %d, dr: %d, dc: %d\n", r, c, dr, dc
1507 *
1508 ************************************/
1509 
simulate_box(int r,int c,unsigned int dr,unsigned int dc)1510 static void simulate_box (int r, int c, unsigned int dr, unsigned int dc)
1511 {
1512    int rr, rmax;
1513 
1514    if ((dr < 1) || (dc < 2)) return;
1515 
1516    dr--;
1517    dc--;
1518    /* Dbp2( "--- r: %d c: %d ---------------------------\n", r, c ); */
1519    SLsmg_gotorc (r, c);
1520    SLsmg_write_string ("+");
1521    simulate_hline (dc-1);
1522    SLsmg_write_string ("+");
1523    /* Dbp2( "--- r: %d c: %d ---------------------------\n", r + dr, c ); */
1524    SLsmg_gotorc (r + dr, c);
1525    SLsmg_write_string ("+");
1526    simulate_hline (dc-1);
1527    SLsmg_write_string ("+");
1528 
1529    rmax = r + dr;
1530    for (rr = r + 1; rr < rmax; rr++)
1531      {
1532       /* Dbp2( "--- r: %d c: %d ---------------------------\n", rr, c ); */
1533 	SLsmg_gotorc (rr, c);
1534 	SLsmg_write_string ("|");
1535       /* Dbp2( "--- r: %d c: %d ---------------------------\n", rr, c + dc ); */
1536 	SLsmg_gotorc (rr, c + dc);
1537 	SLsmg_write_string ("|");
1538      }
1539 }
1540 
1541 /* I would prefer to use real up/down arrows but I cannot depend upon their
1542  * portability.
1543  */
1544 /************************************
1545 * draw_up_arrow
1546 *
1547 * debug print: "r: %d, c: %d\n", r, c
1548 *
1549 ************************************/
1550 
draw_up_arrow(int r,int c)1551 static void draw_up_arrow (int r, int c)
1552 {
1553    /* Dbp2( "--- r: %d c: %d ---------------------------\n", r, c ); */
1554    SLsmg_gotorc (r, c);
1555    SLsmg_write_string ("(-)");
1556 }
1557 
1558 /************************************
1559 * draw_down_arrow
1560 *
1561 * debug print: "r: %d, c: %d\n", r, c
1562 *
1563 ************************************/
1564 
draw_down_arrow(int r,int c)1565 static void draw_down_arrow (int r, int c)
1566 {
1567    /* Dbp2( "--- r: %d c: %d ---------------------------\n", r, c ); */
1568    SLsmg_gotorc (r, c);
1569    SLsmg_write_string ("(+)");
1570 }
1571 
1572 /************************************
1573 * draw_name
1574 *
1575 * debug print: "Name %s, color0: %d, color1: %d, field_width: %d\n", name, color0, color1, field_width
1576 *
1577 ************************************/
1578 
draw_name(char * name,int color0,int color1,unsigned int field_width)1579 static void draw_name (char *name, int color0, int color1, unsigned int field_width)
1580 {
1581    char *s;
1582    unsigned int n;
1583 
1584    s = name;
1585 
1586    while (*s && (*s != '&'))
1587      s++;
1588 
1589    n = (unsigned int) (s - name);
1590    if (n)
1591      {
1592 	SLsmg_set_color (color0);
1593 	SLsmg_write_nchars (name, n);
1594      }
1595 
1596    if (*s != 0)
1597      {
1598 	unsigned int dn;
1599 
1600 	s++;
1601 	SLsmg_set_color (color1);
1602 	SLsmg_write_nchars (s, 1);
1603 	n++;
1604 	SLsmg_set_color (color0);
1605 	if (*s != 0)
1606 	  {
1607 	     s++;
1608 	     dn = strlen (s);
1609 	     SLsmg_write_nchars (s, dn);
1610 	     n += dn;
1611 	  }
1612      }
1613 
1614    if (n < field_width)
1615      SLsmg_write_nstring ("", field_width - n);
1616 }
1617 
1618 /************************************
1619 * draw_menu_bar
1620 *
1621 * debug print: "Menu bar: %x\n", b
1622 *
1623 ************************************/
1624 
draw_menu_bar(Menu_Bar_Type * b)1625 static int draw_menu_bar (Menu_Bar_Type *b)
1626 {
1627    Menu_Node_Type **m;
1628    unsigned int i, imax;
1629    int active;
1630 
1631    /* Dbp2( "--- r: %d c: %d ---------------------------\n", 0, 0 ); */
1632 
1633    SLsmg_gotorc (0, 0);
1634 
1635    SLsmg_set_color (JMENU_COLOR);
1636    SLsmg_write_string (b->prefix_string);
1637 
1638    m = b->subnodes;
1639    imax = b->num_subnodes;
1640    active = -1;
1641 
1642    for (i = 0; i < imax; i++)
1643      {
1644 	Menu_Popup_Type *p;
1645 	char *name;
1646 
1647 	p = (Menu_Popup_Type *) m[i];
1648 	if (p->flags & MENU_ITEM_UNAVAILABLE)
1649 	  continue;
1650 
1651 	b->item_columns[i] = SLsmg_get_column ();
1652 
1653 	if (p->type == MENU_NODE_SEPARATOR)
1654 	  name = "          ";
1655 	else
1656 	  name = p->name;
1657 
1658 	if (p->flags & MENU_SELECTION)
1659 	  {
1660 	     if (p->type == MENU_NODE_POPUP)
1661 	       active = i;
1662 
1663 	     draw_name (name, JMENU_SELECTION_COLOR, JMENU_SELECTED_CHAR_COLOR, 0);
1664 	  }
1665 	else
1666 	  draw_name (name, JMENU_COLOR, JMENU_CHAR_COLOR, 0);
1667 
1668 	SLsmg_set_color (JMENU_COLOR);
1669 	SLsmg_write_string ("   ");
1670      }
1671 
1672    SLsmg_set_color (JMENU_COLOR);
1673    SLsmg_erase_eol ();
1674 
1675    return active;
1676 }
1677 
1678 /************************************
1679 * draw_keystring
1680 *
1681 * debug print: "Menu keystring fun type: %x, color0: %d, color1: %d, field_widht: %d\n", k, color0, color1, field_width
1682 *
1683 ************************************/
1684 
draw_keystring(Menu_Keystring_Fun_Type * k,int color0,int color1,unsigned int field_width)1685 static int draw_keystring (Menu_Keystring_Fun_Type *k, int color0, int color1, unsigned int field_width)
1686 {
1687    int i;
1688    SLang_Key_Type *key, *key_root;
1689    FVOID_STAR fp;
1690    unsigned char type;
1691    char buf[3];
1692    unsigned int best_len;
1693    char *best_keystring;
1694    SLang_Key_Type *best_key;
1695    char *name;
1696 
1697    draw_name (k->name, color0, color1, field_width);
1698 
1699    name = k->keystring;
1700    /* Now try to draw the binding */
1701 
1702    if (NULL == (fp = (FVOID_STAR) SLang_find_key_function(name, CBuf->keymap)))
1703      type = SLKEY_F_INTERPRET;
1704    else type = SLKEY_F_INTRINSIC;
1705 
1706    best_keystring = NULL;
1707    best_len = 0xFFFF;
1708    best_key = NULL;
1709 
1710    key_root = CBuf->keymap->keymap;
1711 
1712    for (i = 0; i < 256; i++, key_root++)
1713      {
1714 # ifdef IBMPC_SYSTEM
1715 	if ((i == 0) || (i == 0xE0))
1716 	  continue;
1717 # endif
1718 
1719 	key = key_root->next;
1720 	if ((key == NULL) && (type == key_root->type))
1721 	  {
1722 	     if (type == SLKEY_F_INTERPRET)
1723 	       {
1724 		  if (strcmp (name, key_root->f.s))
1725 		    continue;
1726 	       }
1727 	     else if ((type != SLKEY_F_INTRINSIC) || (fp != key_root->f.f))
1728 	       continue;
1729 
1730 	     buf[0] = i;
1731 	     buf[1] = 0;
1732 # ifndef IBMPC_SYSTEM
1733 	     if (i == 0)
1734 	       {
1735 		  buf[0] = '^';
1736 		  buf[1] = '@';
1737 		  buf[2] = 0;
1738 	       }
1739 # endif
1740 	     best_keystring = buf;
1741 	     break;
1742 	  }
1743 
1744 	while (key != NULL)
1745 	  {
1746 	     char *s;
1747 	     SLang_Key_Type *this_key = key;
1748 
1749 	     key = key->next;
1750 
1751 	     if (this_key->type != type)
1752 	       continue;
1753 
1754 	     if (type == SLKEY_F_INTERPRET)
1755 	       {
1756 		  if (strcmp (name, this_key->f.s))
1757 		    continue;
1758 	       }
1759 	     else if ((type != SLKEY_F_INTRINSIC) || (fp != this_key->f.f))
1760 	       continue;
1761 
1762 	     s = SLang_make_keystring (this_key->str);
1763 	     if (s == NULL)
1764 	       continue;
1765 
1766 	     if (strlen (s) < best_len)
1767 	       {
1768 		  best_key = this_key;
1769 		  best_len = strlen (s);
1770 	       }
1771 	  }
1772      }
1773 
1774    if (best_keystring == NULL)
1775      {
1776 	if (best_key == NULL)
1777 	  return 0;
1778 
1779 	best_keystring = SLang_make_keystring (best_key->str);
1780 	if (best_keystring == NULL)
1781 	  return 0;
1782      }
1783 
1784    best_len = strlen (best_keystring);
1785    if (best_len > 4)
1786      return 0;
1787 
1788    SLsmg_forward (-4);
1789    SLsmg_set_color (color0);
1790    SLsmg_write_nchars (best_keystring, best_len);
1791    return 0;
1792 }
1793 
1794 /************************************
1795 * draw_popup_menu
1796 *
1797 * debug print: "Menu: %x, r: %d, c: %d\n", p, r, c
1798 *
1799 ************************************/
1800 
draw_popup_menu(Menu_Popup_Type * p,int r,int c)1801 static int draw_popup_menu (Menu_Popup_Type *p, int r, int c)
1802 {
1803    int active_row, active_col;
1804    unsigned int dr, dc;
1805    Menu_Node_Type **l, **lmax;
1806    Menu_Popup_Type *p_active;
1807 
1808    Active_Popup = p;
1809 
1810    if (r == 0)
1811      r = 1;
1812 
1813    dr = p->num_subnodes + 2;
1814    dc = p->min_width + 5 + 4;	       /* allow room for keystring */
1815 
1816    if (c + (int)dc >= Jed_Num_Screen_Cols)
1817      {
1818 	if ((int)dc > Jed_Num_Screen_Cols)
1819 	  c = 0;
1820 	else
1821 	  c = Jed_Num_Screen_Cols - (int)dc;
1822      }
1823 
1824    if (r + (int)dr >= Jed_Num_Screen_Rows)
1825      {
1826 	if ((int)dr >= Jed_Num_Screen_Rows)
1827 	  {
1828 	     r = 1;
1829 	     dr = Jed_Num_Screen_Rows - 1;
1830 	  }
1831 	else
1832 	  r = Jed_Num_Screen_Rows - (int)dr;
1833      }
1834 
1835    SLsmg_set_color_in_region (JMENU_SHADOW_COLOR, r + 1, c + 1, dr, dc);
1836    SLsmg_set_color (JMENU_POPUP_COLOR);
1837    /* SLsmg_fill_region (r, c, dr, dc, ' '); */
1838    if (Jed_Simulate_Graphic_Chars)
1839      simulate_box (r, c, dr, dc);
1840    else
1841      SLsmg_draw_box (r, c, dr, dc);
1842 
1843    p->row = r;
1844    p->column = c;
1845    p->max_row = r + dr;
1846    p->max_col = c + dc;
1847 
1848    /* Make sure a selection is present */
1849    (void) get_selected_menu_item (p);
1850 
1851    l = p->subnodes;
1852    lmax = l + p->num_subnodes;
1853 
1854    if (p->num_subnodes + 2 > dr)
1855      {
1856 	unsigned int page;
1857 	unsigned int nr = dr - 2;
1858 	unsigned int col;
1859 
1860 	col = c + dc - 4;
1861 	page = p->active_node / nr;
1862 	if (page)
1863 	  {
1864 	     l += page * nr;
1865 	     draw_up_arrow (r, col);
1866 	  }
1867 	if (lmax > l + nr)
1868 	  {
1869 	     lmax = l + nr;
1870 	     draw_down_arrow (r + dr - 1, col);
1871 	  }
1872 	else
1873 	  l = lmax - nr;
1874      }
1875 
1876    p->visible_node_offset = (int) (l - p->subnodes);
1877 
1878    c++;
1879    r++;
1880    p_active = NULL;
1881    active_row = r;
1882    active_col = c;
1883 
1884    dc -= 3;
1885 
1886    while (l < lmax)
1887      {
1888 	Menu_Node_Type *m;
1889 	int color0, color1;
1890 
1891 	m = *l;
1892 
1893         /* Dbp2( "--- r: %d c: %d ---------------------------\n", r, c ); */
1894 
1895         SLsmg_gotorc (r, c);
1896 
1897 	color0 = JMENU_POPUP_COLOR;
1898 	color1 = JMENU_CHAR_COLOR;
1899 
1900 	if (m->flags & MENU_SELECTION)
1901 	  {
1902 	     active_row = r;
1903 	     active_col = c + dc;
1904 	     color0 = JMENU_SELECTION_COLOR;
1905 	     color1 = JMENU_SELECTED_CHAR_COLOR;
1906 	  }
1907 
1908 	if ((m->flags & MENU_ACTIVE)
1909 	    && (m->type == MENU_NODE_POPUP))
1910 	  {
1911 	     p_active = (Menu_Popup_Type *)m;
1912 	     p_active->row = active_row;
1913 	     p_active->column = active_col - dc/2;
1914 	  }
1915 
1916 	SLsmg_set_color (color0);
1917 	switch (m->type)
1918 	  {
1919 	   case MENU_NODE_SEPARATOR:
1920 	     SLsmg_write_nchars (" ", 1);
1921 	     if (Jed_Simulate_Graphic_Chars)
1922 	       simulate_hline (dc - 1);
1923 	     else
1924 	       SLsmg_draw_hline (dc-1);
1925 	     SLsmg_write_nchars (" ", 1);
1926 	     break;
1927 
1928 	   case MENU_NODE_POPUP:
1929 	     SLsmg_write_nchars (" ", 1);
1930 	     draw_name (m->name, color0, color1, dc);
1931 	     /* Dbp2( "--- r: %d c: %d ---------------------------\n", r, c + ( dc - 2 ) ); */
1932              SLsmg_gotorc (r, c + (dc - 2));
1933 	     SLsmg_write_nchars (">>>", 3);
1934 	     break;
1935 
1936 	   case MENU_NODE_KEYSTRING:
1937 	     SLsmg_write_nchars (" ", 1);
1938 	     draw_keystring ((Menu_Keystring_Fun_Type *)m, color0, color1, dc);
1939 	     break;
1940 
1941 	   default:
1942 	     SLsmg_write_nchars (" ", 1);
1943 	     draw_name (m->name, color0, color1, dc);
1944 	     break;
1945 	  }
1946 	l++;
1947 	r++;
1948      }
1949 
1950    if (p_active != NULL)
1951      return draw_popup_menu (p_active, p_active->row, p_active->column);
1952 
1953    /* Dbp2( "--- r: %d c: %d ---------------------------\n", active_row, active_col ); */
1954 
1955    SLsmg_gotorc (active_row, active_col);
1956    return 0;
1957 }
1958 
1959 /************************************
1960 * get_active_menubar
1961 *
1962 * debug print: "(void)\n"
1963 *
1964 ************************************/
1965 
get_active_menubar(void)1966 static Menu_Bar_Type *get_active_menubar (void)
1967 {
1968    Menu_Bar_Type *b;
1969 
1970    /* Active_Popup = NULL; */
1971    b = Active_Menu_Bar;
1972 
1973    if (b == NULL)
1974      {
1975 	Buffer *buf = CBuf;
1976 
1977 	if (IN_MINI_WINDOW)
1978 	  {
1979 	     if (NULL == (buf = jed_get_mini_action_buffer ()))
1980 	       return NULL;
1981 	  }
1982 
1983 	if (NULL == (b = buf->menubar))
1984 	  b = Global_Menu_Bar;
1985 
1986 	if (b == NULL)
1987 	  return NULL;
1988 
1989      }
1990    /* Active_Popup = (Menu_Popup_Type *) b; */
1991    return b;
1992 }
1993 
1994 /************************************
1995 * jed_redraw_menus
1996 *
1997 * debug print: "(void)\n"
1998 *
1999 ************************************/
2000 
jed_redraw_menus(void)2001 int jed_redraw_menus (void)
2002 {
2003    Menu_Popup_Type *p;
2004    Menu_Bar_Type *b;
2005    int active;
2006 
2007    return 0;
2008 
2009 # if 0
2010    if (NULL == (b = CBuf->menubar))
2011      b = Global_Menu_Bar;
2012 # else
2013    b = get_active_menubar ();
2014 # endif
2015 
2016    Active_Popup = (Menu_Popup_Type *) b;
2017 
2018    if (b == NULL)
2019      {
2020 	/* Dbp2( "--- r: %d c: %d ---------------------------\n", 0, 0 ); */
2021         SLsmg_gotorc (0, 0);
2022 	SLsmg_set_color (0);
2023 	SLsmg_erase_eol ();
2024 	return 0;
2025      }
2026 
2027    active = draw_menu_bar (b);
2028    if (active == -1)
2029      return 0;
2030 
2031    touch_screen ();
2032 
2033    p = (Menu_Popup_Type *)b->subnodes[active];
2034 
2035    if (0 == (p->flags & MENU_ACTIVE))
2036      {
2037         /* Dbp2( "--- r: %d c: %d ---------------------------\n", 0, b->item_columns[active] ); */
2038 	SLsmg_gotorc (0, b->item_columns[active]);
2039 	return 1;
2040      }
2041 
2042    draw_popup_menu (p, 0, b->item_columns[active]);
2043    return 1;
2044 }
2045 
2046 /* Keyboard Interface */
2047 
2048 /************************************
2049 * find_active_popup
2050 *
2051 * debug print: "(void)\n"
2052 *
2053 ************************************/
2054 
find_active_popup(void)2055 static int find_active_popup (void)
2056 {
2057    Menu_Popup_Type *p;
2058 
2059    if (Active_Menu_Bar == NULL)
2060      return -1;
2061 
2062    p = (Menu_Popup_Type *) Active_Menu_Bar;
2063 
2064    while (1)
2065      {
2066 	Active_Popup = p;
2067 	p = (Menu_Popup_Type *) get_selected_menu_item (p);
2068 
2069 	if ((p == NULL) || (p->type != MENU_NODE_POPUP))
2070 	  return 0;
2071 
2072 	if (0 == (p->flags & MENU_ACTIVE))
2073 	  return 0;
2074 
2075 	if (0 == (p->flags & MENU_POPUP_PREPARED))
2076 	  return select_menu_cmd ();
2077      }
2078 }
2079 
2080 /************************************
2081 * next_menubar_cmd
2082 *
2083 * debug print: "(void)\n"
2084 *
2085 ************************************/
2086 
next_menubar_cmd(void)2087 static int next_menubar_cmd (void)
2088 {
2089    unsigned int flags;
2090    Menu_Popup_Type *p;
2091 
2092    if (NULL == (p = (Menu_Popup_Type *) Active_Menu_Bar))
2093      return -1;
2094 
2095    flags = get_active_node_flags (p) & MENU_ACTIVE;
2096 
2097    /* (void) unselect_active_node ((Menu_Popup_Type *)Active_Menu_Bar); */
2098    (void) select_next_active_node (p, p->active_node, flags);
2099    (void) find_active_popup ();
2100    return 1;
2101 }
2102 
2103 /************************************
2104 * prev_menubar_cmd
2105 *
2106 * debug print: "(void)\n"
2107 *
2108 ************************************/
2109 
prev_menubar_cmd(void)2110 static int prev_menubar_cmd (void)
2111 {
2112    unsigned int flags;
2113    Menu_Popup_Type *p;
2114 
2115    if (NULL == (p = (Menu_Popup_Type *) Active_Menu_Bar))
2116      return -1;
2117 
2118    flags = get_active_node_flags (p) & MENU_ACTIVE;
2119    /* (void) unselect_active_node ((Menu_Popup_Type *)Active_Menu_Bar); */
2120    (void) select_prev_active_node (p, p->active_node, flags);
2121    (void) find_active_popup ();
2122    return 1;
2123 }
2124 
2125 /************************************
2126 * jed_exit_menu_bar
2127 *
2128 * debug print: "(void)\n"
2129 *
2130 ************************************/
2131 
2132 int
jed_exit_menu_bar(void)2133 jed_exit_menu_bar (void)
2134 {
2135    while (Active_Popup != NULL)
2136      {
2137 	unselect_active_node (Active_Popup);
2138 	Active_Popup->active_node = 0;
2139 	Active_Popup->flags &= ~MENU_POPUP_PREPARED;
2140 	Active_Popup = Active_Popup->parent;
2141      }
2142 
2143    Active_Menu_Bar = NULL;
2144    /* Db; */
2145    /* Dbp1( "################################################################\n", 1 ); */
2146    Jed_Menus_Active = 0;
2147    return 1;
2148 }
2149 
2150 /************************************
2151 * down_menu_cmd
2152 *
2153 * debug print: "(void)\n"
2154 *
2155 ************************************/
2156 
down_menu_cmd(void)2157 static int down_menu_cmd (void)
2158 {
2159    if (Active_Popup == NULL)
2160      return -1;
2161 
2162    /* unselect_active_node (Active_Popup); */
2163    select_next_active_node (Active_Popup, Active_Popup->active_node, 0);
2164    return 1;
2165 }
2166 
2167 /************************************
2168 * up_menu_cmd
2169 *
2170 * debug print: "(void)\n"
2171 *
2172 ************************************/
2173 
up_menu_cmd(void)2174 static int up_menu_cmd (void)
2175 {
2176    if (Active_Popup == NULL)
2177      return -1;
2178 
2179    /* unselect_active_node (Active_Popup); */
2180    select_prev_active_node (Active_Popup, Active_Popup->active_node, 0);
2181    return 1;
2182 }
2183 
2184 /************************************
2185 * pgup_menu_cmd
2186 *
2187 * debug print: "(void)\n"
2188 *
2189 ************************************/
2190 
pgup_menu_cmd(void)2191 static int pgup_menu_cmd (void)
2192 {
2193    if (Active_Popup == NULL)
2194      return -1;
2195 
2196    select_next_active_node (Active_Popup, Active_Popup->num_subnodes, 0);
2197    return 1;
2198 }
2199 
2200 /************************************
2201 * pgdn_menu_cmd
2202 *
2203 * debug print: "(void)\n"
2204 *
2205 ************************************/
2206 
pgdn_menu_cmd(void)2207 static int pgdn_menu_cmd (void)
2208 {
2209    if (Active_Popup == NULL)
2210      return -1;
2211 
2212    select_prev_active_node (Active_Popup, 0, 0);
2213    return 1;
2214 }
2215 
2216 /************************************
2217 * execute_keystring
2218 *
2219 * debug print: "Key string: %s\n", s
2220 *
2221 ************************************/
2222 
execute_keystring(char * s)2223 static int execute_keystring (char *s)
2224 {
2225    int (*f)(void);
2226 
2227    /* printf( "File: %s, Line: %d: exec keystring keymap: %x\n", __FILE__, __LINE__, CBuf->keymap ); */
2228 
2229    if (NULL != (f = (int (*)(void)) (SLang_find_key_function(s, CBuf->keymap))))
2230      {
2231       /* printf( "File: %s, Line: %d: exec keystring function: %x\n", __FILE__, __LINE__, f ); */
2232 	return (*f) ();
2233      }
2234 
2235    /* Dbp( "Function: |%s|\n", s ); */
2236 
2237    if ( ( *s == '.' ) ||
2238         !SLang_execute_function( s ) )
2239      SLang_load_string(s);
2240 
2241    /* printf( "File: %s, Line: %d exec keystring load string\n", __FILE__, __LINE__ ); */
2242 
2243    return 1;
2244 }
2245 
2246 /************************************
2247 * get_full_popup_name
2248 *
2249 * debug print: "Menu: %x\n", p
2250 *
2251 ************************************/
2252 
get_full_popup_name(Menu_Popup_Type * p)2253 static char *get_full_popup_name (Menu_Popup_Type *p)
2254 {
2255    Menu_Popup_Type *parent;
2256    unsigned int len;
2257    char *name;
2258    char *s;
2259 
2260    len = strlen (p->name);
2261    parent = p->parent;
2262    while (parent != NULL)
2263      {
2264 	len += 1 + strlen (parent->name);
2265 	parent = parent->parent;
2266      }
2267 
2268    name = SLmalloc (len + 1);
2269    if (name == NULL)
2270      return NULL;
2271 
2272    s = (name + len) - strlen (p->name);
2273    strcpy (s, p->name);
2274    parent = p->parent;
2275    while (parent != NULL)
2276      {
2277 	s--;
2278 	*s = '.';
2279 	len = strlen (parent->name);
2280 	s -= len;
2281 	strncpy (s, parent->name, len);
2282 	parent = parent->parent;
2283      }
2284 
2285    return name;
2286 }
2287 
2288 /************************************
2289 * run_popup_callback
2290 *
2291 * debug print: "Menu: %x, Name: %x\n", p, cb
2292 *
2293 ************************************/
2294 
run_popup_callback(Menu_Popup_Type * p,SLang_Name_Type * cb)2295 static int run_popup_callback (Menu_Popup_Type *p, SLang_Name_Type *cb)
2296 {
2297    char *name;
2298 
2299    if (NULL == (name = get_full_popup_name (p)))
2300      return -1;
2301 
2302    if (-1 == SLang_push_string (name))
2303      {
2304 	SLfree (name);
2305 	return -1;
2306      }
2307    SLfree (name);
2308 
2309    if (0 != SLexecute_function (cb))
2310      return -1;
2311 
2312    return 0;
2313 }
2314 
2315 /************************************
2316 * prepare_popup
2317 *
2318 * debug print: "Menu: %x\n", p
2319 *
2320 ************************************/
2321 
prepare_popup(Menu_Popup_Type * p)2322 static int prepare_popup (Menu_Popup_Type *p)
2323 {
2324    SLang_Name_Type *cb;
2325 
2326    if (NULL != (cb = p->select_popup_callback))
2327      {
2328 	free_menu_popup_subnodes (p);
2329 	if (-1 == run_popup_callback (p, cb))
2330 	  return -1;
2331      }
2332 
2333    if (NULL != (cb = p->tweak_popup_callback))
2334      {
2335 	if (-1 == run_popup_callback (p, cb))
2336 	  return -1;
2337      }
2338 
2339    p->flags |= MENU_POPUP_PREPARED;
2340    return 0;
2341 }
2342 
2343 /************************************
2344 * jGtkPreparePopup
2345 *
2346 * debug print: "p: %x, cb: %x\n", p, cb
2347 *
2348 ************************************/
2349 
2350 static int
jGtkPreparePopup(Menu_Popup_Type * p,SLang_Name_Type * cb)2351 jGtkPreparePopup( Menu_Popup_Type *p, SLang_Name_Type *cb )
2352 {
2353    /* SLang_Name_Type *cb; */
2354 
2355    if ( cb )
2356      {
2357 	free_menu_popup_subnodes( p );
2358 	if ( -1 == run_popup_callback( p, cb ) )
2359 	  return -1;
2360      }
2361 
2362    if (NULL != (cb = p->tweak_popup_callback))
2363      {
2364 	if (-1 == run_popup_callback (p, cb))
2365 	  return -1;
2366      }
2367 
2368    p->flags |= MENU_POPUP_PREPARED;
2369    return 0;
2370 }
2371 
2372 /************************************
2373 * execMenuTbCmd
2374 *
2375 * debug print: "Menu: %x\n", m
2376 *
2377 ************************************/
2378 
2379 static int
execMenuTbCmd(Menu_Node_Type * m)2380 execMenuTbCmd( Menu_Node_Type *m )
2381 {
2382    Menu_Popup_Type *p;
2383    Menu_Popup_Type *mp = ( Menu_Popup_Type * ) m;
2384    Menu_C_Fun_Type *c;
2385    SLang_Name_Type *nt;
2386    char *str;
2387 
2388    if ( activeTopSubmenu )
2389      {
2390 	if ( m->type != MENU_NODE_POPUP )
2391 	  {
2392 	 /* Dbp1( "Deselecting: %x\n", activeTopSubmenu->parent->subMenu ); */
2393 	     gtk_menu_shell_deselect( ( GtkMenuShell * ) activeTopSubmenu->parent->subMenu );
2394 	     activeTopSubmenu = NULL;
2395 	  }
2396      }
2397 
2398    /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
2399 
2400    if (m == NULL)
2401      return -1;
2402 
2403    switch (m->type)
2404      {
2405       case MENU_NODE_POPUP:
2406 # if 0
2407 	m->flags |= MENU_ACTIVE;
2408 	p = (Menu_Popup_Type *) m;
2409 # else
2410 	/* Do it this way to avoid DEC C ansi-aliasing warning. */
2411 	p = (Menu_Popup_Type *) m;
2412 	/* p->flags |= MENU_ACTIVE; */
2413 # endif
2414 	if (-1 == prepare_popup (p))
2415 	  return -1;
2416 	Active_Popup = p;
2417 	/* select_next_active_node (p, p->num_subnodes, 0); */
2418 
2419         /* Dbp1( "Activate: %x\n", m ); */
2420 
2421         /****/
2422         gtk_menu_shell_select_item( ( GtkMenuShell * ) mp->parent->subMenu,
2423 				    p->menuItem );
2424 
2425         if ( !activeTopSubmenu ) activeTopSubmenu = mp;
2426         /*****/
2427 
2428         /*******
2429         gtk_menu_shell_select_first( ( GtkMenuShell * ) mp->parent->subMenu,
2430 				    1 );
2431         *******/
2432 # if 0
2433         gtk_menu_popup( ( GtkMenu * ) mp->subMenu, NULL, NULL,
2434 			/* mp->parent->subMenu, */
2435 			/* mp->parent->menuItem, */
2436 			NULL, NULL, 0,
2437 			gtk_get_current_event_time() );
2438 # endif
2439         /*************
2440         gtk_menu_shell_activate_item( ( GtkMenuShell * ) mp->parent->subMenu,
2441 				      p->menuItem,
2442 				      1 );
2443         *********/
2444 
2445 	return 1;
2446 
2447       case MENU_NODE_FUN_SLANG:
2448         /* Dbp( "MENU_NODE_FUN_SLANG: %d\n", 1 ); */
2449 	nt = ((Menu_SLang_Fun_Type *) m)->slang_fun;
2450 	/* jed_exit_menu_bar (); */
2451 	if (nt == NULL)
2452 	  return -1;
2453 	if ((-1 == SLang_start_arg_list ())
2454 	    || (-1 == SLang_push_anytype (((Menu_SLang_Fun_Type*)m)->client_data))
2455 	    || (-1 == SLang_end_arg_list ()))
2456 	  return -1;
2457 
2458         /* Dbp( "SLexecute_functions: |%x|\n", nt ); */
2459 
2460 	return SLexecute_function (nt);
2461 
2462       case MENU_NODE_KEYSTRING:
2463         /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
2464 	str = ((Menu_Keystring_Fun_Type *) m)->keystring;
2465 	/* printf( "File: %s, Line: %d: String to execute: %s\n", __FILE__, __LINE__, str ); */
2466 	/* Grab a copy while it is still available */
2467 	if (NULL == SLang_create_slstring (str))
2468 	  return -1;
2469 	/* jed_exit_menu_bar (); */
2470 
2471         /* Dbp( "execute_keystring: |%s|\n", str ); */
2472 	(void) execute_keystring (str);
2473 	SLang_free_slstring (str);
2474 	break;
2475 
2476       case MENU_NODE_FUN_C:
2477         /* Dbp( "MENU_NODE_FUN_C: %d\n", 1 ); */
2478 	c = (Menu_C_Fun_Type *) m;
2479 	/* jed_exit_menu_bar (); */
2480 	if (c->c_fun != NULL)
2481 	  return -1;
2482 	return c->c_fun ();
2483       case MENU_NODE_TYPEDKEYS:
2484         /* Dbp2( "m: %x keystring: %x\n", m, (( Menu_Keystring_Fun_Type * ) m)->keystring ); */
2485 	str = (( Menu_Keystring_Fun_Type * ) m)->keystring;
2486 	return( jgtk_createKeyEvents( str ) );
2487      }
2488    return 0;
2489 }
2490 
2491 static int
execMenuTbCmdNode(Menu_Node_Type * m)2492 execMenuTbCmdNode( Menu_Node_Type *m )
2493 {
2494    /* Menu_Popup_Type *p; */
2495    Menu_C_Fun_Type *c;
2496    SLang_Name_Type *nt;
2497    char *str;
2498 
2499    /* Dbp1( "m->name: |%s|\n", m->name ); */
2500 
2501    /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
2502 
2503    if (m == NULL)
2504      return -1;
2505 
2506    switch (m->type)
2507      {
2508       case MENU_NODE_POPUP:
2509         /* Dbp1( "Popup node type should not occur here: %x\n", m ); */
2510         return( -1 );
2511 # if 0
2512 #  if 0
2513 	m->flags |= MENU_ACTIVE;
2514 	p = (Menu_Popup_Type *) m;
2515 #  else
2516 	/* Do it this way to avoid DEC C ansi-aliasing warning. */
2517 	p = (Menu_Popup_Type *) m;
2518 	p->flags |= MENU_ACTIVE;
2519 #  endif
2520 	if (-1 == prepare_popup (p))
2521 	  return -1;
2522 	Active_Popup = p;
2523 	select_next_active_node (p, p->num_subnodes, 0);
2524 	return 1;
2525 # endif
2526 
2527       case MENU_NODE_FUN_SLANG:
2528         /* Dbp( "MENU_NODE_FUN_SLANG: %d\n", 1 ); */
2529 	nt = ((Menu_SLang_Fun_Type *) m)->slang_fun;
2530 	/* jed_exit_menu_bar (); */
2531 	if (nt == NULL)
2532 	  return -1;
2533 	if ((-1 == SLang_start_arg_list ())
2534 	    || (-1 == SLang_push_anytype (((Menu_SLang_Fun_Type*)m)->client_data))
2535 	    || (-1 == SLang_end_arg_list ()))
2536 	  return -1;
2537 
2538         /* Dbp( "SLexecute_functions: |%x|\n", nt ); */
2539 
2540 	return SLexecute_function (nt);
2541 
2542       case MENU_NODE_KEYSTRING:
2543         /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
2544 	str = ((Menu_Keystring_Fun_Type *) m)->keystring;
2545 	/* printf( "File: %s, Line: %d: String to execute: %s\n", __FILE__, __LINE__, str ); */
2546 	/* Grab a copy while it is still available */
2547 	if (NULL == SLang_create_slstring (str))
2548 	  return -1;
2549 	/* jed_exit_menu_bar (); */
2550 
2551         /* Dbp( "execute_keystring: |%s|\n", str ); */
2552 	(void) execute_keystring (str);
2553 	SLang_free_slstring (str);
2554 	break;
2555 
2556       case MENU_NODE_FUN_C:
2557         /* Dbp( "MENU_NODE_FUN_C: %d\n", 1 ); */
2558 	c = (Menu_C_Fun_Type *) m;
2559 	/* jed_exit_menu_bar (); */
2560 	if (c->c_fun != NULL)
2561 	  return -1;
2562 	return c->c_fun ();
2563       case MENU_NODE_TYPEDKEYS:
2564         /* Dbp2( "m: %x keystring: %x\n", m, (( Menu_Keystring_Fun_Type * ) m)->keystring ); */
2565 	str = (( Menu_Keystring_Fun_Type * ) m)->keystring;
2566 	return( jgtk_createKeyEvents( str ) );
2567      }
2568    return 0;
2569 }
2570 
2571 /************************************
2572 * select_menu_cmd
2573 *
2574 * debug print: "(void)\n"
2575 *
2576 ************************************/
2577 
2578 static int
select_menu_cmd(void)2579 select_menu_cmd (void)
2580 {
2581    return( execMenuTbCmd( get_selected_menu_item( Active_Popup ) ) );
2582 }
2583 
2584 /************************************
2585 * back_menu_cmd
2586 *
2587 * debug print: "(void)\n"
2588 *
2589 ************************************/
2590 
back_menu_cmd(void)2591 static int back_menu_cmd (void)
2592 {
2593    if ((Active_Popup == NULL)
2594        || (Active_Popup == (Menu_Popup_Type *)Active_Menu_Bar)
2595        || (Active_Popup->parent == (Menu_Popup_Type *) Active_Menu_Bar))
2596      return jed_exit_menu_bar ();
2597 
2598    Active_Popup->flags &= ~(MENU_ACTIVE|MENU_POPUP_PREPARED);
2599    Active_Popup = Active_Popup->parent;
2600    return 1;
2601 }
2602 
2603 /************************************
2604 * find_subnode_via_char
2605 *
2606 * debug print: "Menu: %x, ch: %c\n", p, ch
2607 *
2608 ************************************/
2609 
find_subnode_via_char(Menu_Popup_Type * p,char ch)2610 static Menu_Node_Type *find_subnode_via_char (Menu_Popup_Type *p, char ch)
2611 {
2612    Menu_Node_Type **l, **lmax;
2613    unsigned int two;
2614 
2615    if (p == NULL)
2616      return NULL;
2617 
2618    two = 2;
2619 
2620    while (two)
2621      {
2622 	l = p->subnodes;
2623 	lmax = l + p->num_subnodes;
2624 
2625 	while (l < lmax)
2626 	  {
2627 	     Menu_Node_Type *m;
2628 	     char *s;
2629 
2630 	     m = *l++;
2631 
2632 	     if (m->type == MENU_NODE_SEPARATOR)
2633 	       continue;
2634 
2635 	     if (m->flags & MENU_ITEM_UNAVAILABLE)
2636 	       continue;
2637 
2638 	     s = strchr (m->name, '&');
2639 	     if (s == NULL)
2640 	       continue;
2641 
2642 	     if (s[1] == ch)
2643 	       return m;
2644 	  }
2645 
2646 	ch = (char) CHANGE_CASE(ch);
2647 	two--;
2648      }
2649 
2650    return NULL;
2651 }
2652 
2653 /************************************
2654 * select_via_char_cmd
2655 *
2656 * debug print: "(void)\n"
2657 *
2658 ************************************/
2659 
select_via_char_cmd(void)2660 static int select_via_char_cmd (void)
2661 {
2662    Menu_Node_Type *m;
2663 
2664    m = find_subnode_via_char (Active_Popup, (char) SLang_Last_Key_Char);
2665    if (m == NULL)
2666      return -1;
2667 
2668    set_node_selection (Active_Popup, m);
2669    return select_menu_cmd ();
2670 }
2671 
2672 static SLKeyMap_List_Type *Menu_Keymap;
2673 
2674 static SLKeymap_Function_Type Menu_Keymap_Functions [] =
2675 {
2676    {"next_menubar_menu", next_menubar_cmd},
2677    {"prev_menubar_menu", prev_menubar_cmd},
2678    {"exit_menubar",	jed_exit_menu_bar},
2679    {"next_menu_item",	down_menu_cmd},
2680    {"prev_menu_item",	up_menu_cmd},
2681    {"top_menu_item",	pgup_menu_cmd},
2682    {"bot_menu_item",	pgdn_menu_cmd},
2683    {"select_menu_item", select_menu_cmd},
2684    {"back_menu",	back_menu_cmd},
2685 
2686    {NULL, NULL}
2687 };
2688 
2689 # ifndef IBMPC_SYSTEM
2690 #  ifdef HAS_MOUSE
2691 static int xterm_mouse_cmd (void);
2692 #  endif
2693 # endif
2694 
2695 /************************************
2696 * init_menu_keymap
2697 *
2698 * debug print: "(void)\n"
2699 *
2700 ************************************/
2701 
init_menu_keymap(void)2702 static int init_menu_keymap (void)
2703 {
2704    int ch;
2705    char simple[3];
2706 
2707    if (NULL == (Menu_Keymap = SLang_create_keymap ("menu", NULL)))
2708      return -1;
2709 
2710    Menu_Keymap->functions = Menu_Keymap_Functions;
2711 
2712    simple[1] = 0;
2713    for (ch = 0; ch < 256; ch++)
2714      {
2715 	simple[0] = (char) ch;
2716 	SLkm_define_key (simple, (FVOID_STAR) select_via_char_cmd, Menu_Keymap);
2717      }
2718    simple [0] = 27;
2719    simple [2] = 0;
2720    for (ch = 'a'; ch <= 'z'; ch++)
2721      {
2722 	simple [1] = (char) ch;
2723 	SLkm_define_key (simple, (FVOID_STAR) select_via_char_cmd, Menu_Keymap);
2724      }
2725 
2726    SLkm_define_key (" ", (FVOID_STAR) back_menu_cmd, Menu_Keymap);
2727    SLkm_define_key ("^?", (FVOID_STAR) back_menu_cmd, Menu_Keymap);
2728    SLkm_define_key ("^H", (FVOID_STAR) back_menu_cmd, Menu_Keymap);
2729    SLkm_define_key ("^G", (FVOID_STAR) jed_exit_menu_bar, Menu_Keymap);
2730    SLkm_define_key ("^Z", (FVOID_STAR) sys_spawn_cmd, Menu_Keymap);
2731    SLkm_define_key ("^M", (FVOID_STAR) select_menu_cmd, Menu_Keymap);
2732 
2733 # ifndef IBMPC_SYSTEM
2734    SLkm_define_key ("\033[A", (FVOID_STAR) up_menu_cmd, Menu_Keymap);
2735    SLkm_define_key ("\033OA", (FVOID_STAR) up_menu_cmd, Menu_Keymap);
2736    SLkm_define_key ("\033[B", (FVOID_STAR) down_menu_cmd, Menu_Keymap);
2737    SLkm_define_key ("\033OB", (FVOID_STAR) down_menu_cmd, Menu_Keymap);
2738    SLkm_define_key ("\033[C", (FVOID_STAR) next_menubar_cmd, Menu_Keymap);
2739    SLkm_define_key ("\033OC", (FVOID_STAR) next_menubar_cmd, Menu_Keymap);
2740    SLkm_define_key ("\033[D", (FVOID_STAR) prev_menubar_cmd, Menu_Keymap);
2741    SLkm_define_key ("\033OD", (FVOID_STAR) prev_menubar_cmd, Menu_Keymap);
2742    SLkm_define_key ("\033[5~", (FVOID_STAR) pgup_menu_cmd, Menu_Keymap);
2743    SLkm_define_key ("\033[6~", (FVOID_STAR) pgdn_menu_cmd, Menu_Keymap);
2744 #  ifdef __unix__
2745    SLkm_define_key ("^(ku)", (FVOID_STAR) up_menu_cmd, Menu_Keymap);
2746    SLkm_define_key ("^(kd)", (FVOID_STAR) down_menu_cmd, Menu_Keymap);
2747    SLkm_define_key ("^(kr)", (FVOID_STAR) next_menubar_cmd, Menu_Keymap);
2748    SLkm_define_key ("^(kl)", (FVOID_STAR) prev_menubar_cmd, Menu_Keymap);
2749    SLkm_define_key ("^(kP)", (FVOID_STAR) pgup_menu_cmd, Menu_Keymap);
2750    SLkm_define_key ("^(kN)", (FVOID_STAR) pgdn_menu_cmd, Menu_Keymap);
2751 #  endif
2752 #  ifdef HAS_MOUSE
2753    SLkm_define_key ("\033[M", (FVOID_STAR) xterm_mouse_cmd, Menu_Keymap);
2754 #  endif
2755 # else				       /* IBMPC_SYSTEM */
2756 #  include "doskeys.h"
2757 
2758    SLkm_define_key (PC_UP, (FVOID_STAR) up_menu_cmd, Menu_Keymap);
2759    SLkm_define_key (PC_UP1, (FVOID_STAR) up_menu_cmd, Menu_Keymap);
2760    SLkm_define_key (PC_DN, (FVOID_STAR) down_menu_cmd, Menu_Keymap);
2761    SLkm_define_key (PC_DN1, (FVOID_STAR) down_menu_cmd, Menu_Keymap);
2762    SLkm_define_key (PC_RT, (FVOID_STAR) next_menubar_cmd, Menu_Keymap);
2763    SLkm_define_key (PC_RT1, (FVOID_STAR) next_menubar_cmd, Menu_Keymap);
2764    SLkm_define_key (PC_LT, (FVOID_STAR) prev_menubar_cmd, Menu_Keymap);
2765    SLkm_define_key (PC_LT1, (FVOID_STAR) prev_menubar_cmd, Menu_Keymap);
2766    SLkm_define_key (PC_PGUP, (FVOID_STAR) pgup_menu_cmd, Menu_Keymap);
2767    SLkm_define_key (PC_PGUP1, (FVOID_STAR) pgup_menu_cmd, Menu_Keymap);
2768    SLkm_define_key (PC_PGDN, (FVOID_STAR) pgdn_menu_cmd, Menu_Keymap);
2769    SLkm_define_key (PC_PGDN1, (FVOID_STAR) pgdn_menu_cmd, Menu_Keymap);
2770 # endif
2771 
2772 # ifdef HAS_MOUSE
2773    SLkm_define_key ("\033^@", (FVOID_STAR) jed_mouse_cmd, Menu_Keymap);
2774 # endif
2775 
2776    /* Toolbar callback key */
2777 
2778 /*   SLkm_define_key( TB_CMD_KEY_SEQ, (FVOID_STAR) jed_select_menu_bar, Global_Map ); */
2779    SLkm_define_key( TB_SEL_KEY_SEQ, (FVOID_STAR) jGtkExecTB, Global_Map );
2780    /* SLkm_define_key( TB_EXE_KEY_SEQ, (FVOID_STAR) jGtkExecTB, Menu_Keymap ); */
2781 
2782    return 0;
2783 }
2784 
2785 /* key_interpret */
2786 static int
jGtkExecTB()2787 jGtkExecTB()
2788 {
2789 
2790    activeTopSubmenu = NULL;
2791 
2792    if ( actTBCmdNode )
2793      {
2794      /* execTBCmd( actTBCmd->path ); */
2795 	execMenuTbCmdNode( actTBCmdNode );
2796 	actTBCmdNode = NULL;
2797       /* jed_redraw_screen( 1 ); */
2798       /* update((Line *) NULL, 1, 0, 1); // File: screen.c */
2799 	SLang_restart( 1 );
2800 	touch_screen();
2801      }
2802 
2803    /* Dbp1( "actTBCmdNode: %x\n", actTBCmdNode ); */
2804 
2805    return( 0 );
2806 }
2807 
2808 static int
jGtkFeedTBKeySeq(void)2809 jGtkFeedTBKeySeq(void)
2810 {
2811 
2812    /* Dbp2( "Key: %d: |%c|\n", tbExeKeySeq[tbExeKeyInx], tbExeKeySeq[tbExeKeyInx] ); */
2813 
2814    return( tbExeKeySeq[tbExeKeyInx++] );
2815 }
2816 
2817 /************************************
2818 * jed_menu_do_key
2819 *
2820 * debug print: "(void)\n"
2821 *
2822 ************************************/
2823 
2824 SLang_Key_Type *
jed_menu_do_key(void)2825 jed_menu_do_key (void)
2826 {
2827    int ch;
2828 
2829    if ( tbInputSelected )
2830      {
2831       /* Dbp1( "ActTBCmdNode: |%x|\n", actTBCmdNode ); */
2832       /* tbExecSlangFlag = 1; */
2833 	tbInputSelected = 0;
2834       /* tbActive = 0; */
2835       /* Db; */
2836       /* Dbp1( "################################################################\n", 1 ); */
2837 	Jed_Menus_Active = 0;
2838 
2839 	tbExeKeyInx = 0;
2840 
2841       /* Return SLang_do_key( Menu_Keymap, jed_getkey ); */
2842 	return SLang_do_key( Menu_Keymap, jGtkFeedTBKeySeq );
2843      }
2844    else
2845      {
2846 	if ( Executing_Keyboard_Macro ||
2847 	     ( Read_This_Character != NULL ) )
2848 	  return SLang_do_key( Menu_Keymap, jed_getkey );
2849 
2850 	ch = my_getkey();
2851 
2852 	if ( SLKeyBoard_Quit || SLang_get_error () )
2853 	  {
2854 	     jed_exit_menu_bar();
2855 	     return NULL;
2856 	  }
2857 
2858 	if ( ch == 27 )		       /* ESC */
2859 	  {
2860 	     int tsecs = 2;
2861 	     if ( 0 == input_pending( &tsecs ) )
2862 	       ch = 127;
2863 	  }
2864 	ungetkey (&ch);
2865 
2866 	return SLang_do_key( Menu_Keymap, jed_getkey );
2867      }
2868 }
2869 
2870 /************************************
2871 * exec_menubar_callback
2872 *
2873 * debug print: "Menu bar: %x, Name types: %x\n", b, ntp
2874 *
2875 ************************************/
2876 
exec_menubar_callback(Menu_Bar_Type * b,SLang_Name_Type ** ntp)2877 static int exec_menubar_callback (Menu_Bar_Type *b, SLang_Name_Type **ntp)
2878 {
2879    SLang_Name_Type *nt;
2880 
2881    nt = *ntp;
2882    if (nt == NULL)
2883      return 0;
2884 
2885    if (SLang_get_error ())
2886      return -1;
2887 
2888    if (-1 == SLang_push_string (b->name))
2889      return -1;
2890 
2891    if (-1 == SLexecute_function (nt))
2892      {
2893 	if (Active_Menu_Bar == b)      /* disable callback */
2894 	  {
2895 # if SLANG_VERSION > 10400
2896 	     SLang_free_function (nt);
2897 # endif
2898 	     *ntp = NULL;
2899 	  }
2900 	return -1;
2901      }
2902 
2903    return 0;
2904 }
2905 
2906 /************************************
2907 * jed_notify_menu_buffer_changed
2908 *
2909 * debug print: "(void)\n"
2910 *
2911 ************************************/
2912 
jed_notify_menu_buffer_changed(void)2913 void jed_notify_menu_buffer_changed (void)
2914 {
2915    Menu_Bar_Type *b;
2916    int err;
2917 
2918    if (NULL == (b = get_active_menubar ()))
2919      return;
2920 
2921    err = SLang_get_error ();
2922    SLang_set_error (0);
2923    (void) exec_menubar_callback (b, &b->init_callback);
2924    if (SLang_get_error () == 0)
2925      SLang_set_error (err);
2926 }
2927 
2928 static int
jGtkSelectTB(void)2929 jGtkSelectTB(void)
2930 {
2931    /* if ( IN_MINI_WINDOW ) Return( -1 ); */
2932    tbInputSelected = 1;
2933    Jed_Menus_Active = 1;
2934    return 0;
2935 }
2936 
2937 /************************************
2938 * jed_select_menu_bar
2939 *
2940 * debug print: "(void)\n"
2941 *
2942 ************************************/
2943 
2944 int
jed_select_menu_bar(void)2945 jed_select_menu_bar (void)
2946 {
2947    Menu_Popup_Type *p;
2948    Menu_Node_Type **l, **lmax;
2949 
2950    /* Db; */
2951 
2952    if (IN_MINI_WINDOW)
2953      {
2954 	/* For now do not allow access to menus from the minibuffer
2955 	 * since the minibuffer is not recursive
2956 	 */
2957 	return -1;
2958      }
2959 
2960 # if 0
2961    if ( tbActive )
2962      {
2963 	Dbp( "Toolbar activated %d\n", 1 );
2964 	tbInputSelected = 1;
2965      }
2966    else
2967 # endif
2968      {
2969       /* Dbp( "Menus activate %d\n", 1 ); */
2970 	if (NULL == (Active_Menu_Bar = get_active_menubar ()))
2971 	  return -1;
2972 
2973 	p = (Menu_Popup_Type *) Active_Menu_Bar;
2974 	Active_Popup = p;
2975 
2976 	l = p->subnodes;
2977 	lmax = l + p->num_subnodes;
2978 
2979    /* Reset each sub-node to its default value.  This is necessary
2980     * to ensure that keyboard macros will work when one switches from
2981     * one node to another via next/prev_menubar_cmd functions.
2982     */
2983 	while (l < lmax)
2984 	  {
2985 	     Menu_Popup_Type *pp = (Menu_Popup_Type *) *l++;
2986 
2987 	     if (pp->type == MENU_NODE_POPUP)
2988 	       {
2989 		  (void) unselect_active_node (pp);
2990 		  pp->active_node = 0;
2991 	       }
2992 	  }
2993 
2994 	p->active_node = 0;
2995 
2996 	if ( -1 == exec_menubar_callback( Active_Menu_Bar, &Active_Menu_Bar->select_callback ) )
2997 	  {
2998 	     jed_exit_menu_bar ();
2999 	     return -1;
3000 	  }
3001 
3002       /* Db; */
3003       /* Dbp1( "######################################################\n", 1 ); */
3004       /* ( void ) get_selected_menu_item (p); */
3005       /* Dbp1( "######################################################\n", 1 ); */
3006      }
3007 
3008    touch_screen ();
3009    /* Db; */
3010    /* Dbp1( "################################################################\n", 1 ); */
3011    /* Jed_Menus_Active = 1; */
3012    return 0;
3013 }
3014 
3015 /* Interpreter interface */
3016 
3017 /************************************
3018 * find_menu_node1
3019 *
3020 * debug print: "Menu: %x, Name: %s, stop at last popup: %d\n", m, name, stop_at_last_popup
3021 *
3022 ************************************/
3023 
find_menu_node1(Menu_Popup_Type * m,char * name,int stop_at_last_popup)3024 static Menu_Node_Type *find_menu_node1 (Menu_Popup_Type *m,
3025 					char *name,
3026 					int stop_at_last_popup)
3027 {
3028    char *name_end;
3029    Menu_Node_Type **l, **lmax;
3030 
3031    name_end = strchr (name, '.');
3032    if (name_end == NULL)
3033      name_end = name + strlen (name);
3034 
3035    l = m->subnodes;
3036    lmax = l + m->num_subnodes;
3037 
3038    while (l < lmax)
3039      {
3040 	Menu_Popup_Type *p;
3041 
3042 	p = (Menu_Popup_Type *) *l++;
3043 
3044 	if (0 == menu_name_eqs (p->name, name, name_end))
3045 	  continue;
3046 
3047 	if (*name_end == 0)
3048 	  {
3049 	     if (stop_at_last_popup
3050 		 && ((p->type != MENU_NODE_POPUP)
3051 		     || (p->type != MENU_NODE_MENUBAR)))
3052 	       return (Menu_Node_Type *)m;
3053 
3054 	     return (Menu_Node_Type *)p;
3055 	  }
3056 
3057 	if (p->type == MENU_NODE_POPUP)
3058 	  return find_menu_node1 (p, name_end + 1, stop_at_last_popup);
3059 
3060 	return NULL;
3061      }
3062 
3063    return NULL;
3064 }
3065 
3066 /************************************
3067 * find_menu_node
3068 *
3069 * debug print: "Name: %s, stop at last popup: %d\n", name, stop_at_last_popup
3070 *
3071 ************************************/
3072 
find_menu_node(char * name,int stop_at_last_popup)3073 static Menu_Node_Type *find_menu_node (char *name, int stop_at_last_popup)
3074 {
3075    char *s;
3076    Menu_Node_Type *m;
3077 
3078    m = (Menu_Node_Type *) menu_find_menu_bar (name, 1);
3079    if (m == NULL)
3080      return m;
3081 
3082    s = strchr (name, '.');
3083    if (s == NULL)
3084      return m;
3085 
3086    m = find_menu_node1 ((Menu_Popup_Type *)m, s + 1, stop_at_last_popup);
3087 
3088    if (m == NULL)
3089      SLang_verror (SL_INTRINSIC_ERROR,
3090 		   "Unable to find menu node %s",
3091 		   name);
3092    return m;
3093 }
3094 
3095 /************************************
3096 * find_menu_popup
3097 *
3098 * debug print: "Name: %s\n", name
3099 *
3100 ************************************/
3101 
find_menu_popup(char * name)3102 static Menu_Popup_Type *find_menu_popup (char *name)
3103 {
3104    Menu_Popup_Type *m;
3105 
3106    m = (Menu_Popup_Type *) find_menu_node (name, 0);
3107    if (m == NULL)
3108      return m;
3109 
3110    if ((m->type != MENU_NODE_POPUP)
3111        && (m->type != MENU_NODE_MENUBAR))
3112      {
3113 	SLang_verror (SL_INVALID_PARM,
3114 		      "%s is not a menu node", name);
3115 	return NULL;
3116      }
3117 
3118    return m;
3119 }
3120 
3121 /* If name is NULL or non-existent, then insert at end */
3122 /************************************
3123 * find_where_to_insert
3124 *
3125 * debug print: "Menu: %x, Name: %s\n", p, name
3126 *
3127 ************************************/
3128 
find_where_to_insert(Menu_Popup_Type * p,char * name)3129 static unsigned int find_where_to_insert (Menu_Popup_Type *p, char *name)
3130 {
3131    unsigned int i, num;
3132 
3133    num = p->num_subnodes;
3134 
3135    if (name != NULL) for (i = 0; i < num; i++)
3136      {
3137 	if (0 == strcmp (name, p->subnodes[i]->name))
3138 	  return i;
3139      }
3140    return num;
3141 }
3142 
3143 /************************************
3144 * create_menu_bar_cmd
3145 *
3146 * debug print: "Name: %s\n", name
3147 *
3148 ************************************/
3149 
3150 static void
create_menu_bar_cmd(char * name)3151 create_menu_bar_cmd( char *name )
3152 {
3153    /* gtkCreateMenuBarCmd( name ); */
3154 
3155    if ( 0 == strcmp( "Global", name ) )
3156      {
3157 	Menu_Bar_Type *g = create_menu_bar( name, 5 );
3158 	if ( g != NULL )
3159 	  {
3160 	     jed_delete_menu_bar( Global_Menu_Bar );
3161 	     jGtkCreateMenuBarCmd( g );
3162       /* Global_Menu_Bar = g; */
3163 	     if ( !Active_Menu_Bar )
3164 	       {
3165 		  gtkSetBufferMenuBarCmd( name );
3166 	       }
3167 	  }
3168 	Global_Menu_Bar = g;
3169 	return;
3170      }
3171 
3172    if ( NULL != menu_find_menu_bar( name, 0 ) )
3173      return;
3174 
3175    jGtkCreateMenuBarCmd( create_menu_bar( name, 5 ) );
3176 }
3177 
3178 /************************************
3179 * set_buffer_menu_bar_cmd
3180 *
3181 * debug print: "Name: %s\n", name
3182 *
3183 ************************************/
3184 
3185 static void
set_buffer_menu_bar_cmd(char * name)3186 set_buffer_menu_bar_cmd (char *name)
3187 {
3188    Menu_Bar_Type *b;
3189 
3190    gtkSetBufferMenuBarCmd( name );
3191    b = menu_find_menu_bar (name, 1);
3192    if (b == NULL)
3193      return;
3194 
3195    if ( b != CBuf->menubar )
3196      {
3197 	jed_delete_menu_bar (CBuf->menubar);
3198 	CBuf->menubar = b;
3199 	b->num_refs += 1;
3200      }
3201 }
3202 
3203 /************************************
3204 * pop_where_to_insert
3205 *
3206 * debug print: "Menu: %x, where: %d\n", p, where
3207 *
3208 ************************************/
3209 
pop_where_to_insert(Menu_Popup_Type * p,unsigned int * where)3210 static int pop_where_to_insert (Menu_Popup_Type *p, unsigned int *where)
3211 {
3212    if (SLang_peek_at_stack () == SLANG_STRING_TYPE)
3213      {
3214 	char *s;
3215 
3216 	if (-1 == SLang_pop_slstring (&s))
3217 	  return -1;
3218 	*where = find_where_to_insert (p, s);
3219 	SLang_free_slstring (s);
3220 	return 0;
3221      }
3222 
3223    if (-1 == SLang_pop_uinteger (where))
3224      return -1;
3225 
3226    return 0;
3227 }
3228 
3229 /************************************
3230 * insert_popup_menu_cmd
3231 *
3232 * debug print: "Dest: |%s|, Menu: |%s|\n", dest, menu
3233 *
3234 ************************************/
3235 
3236 static void
insert_popup_menu_cmd(char * dest,char * menu)3237 insert_popup_menu_cmd (char *dest, char *menu)
3238 {
3239    Menu_Popup_Type *m;
3240    unsigned int where;
3241 
3242    m = find_menu_popup (dest);
3243 
3244    if (m == NULL)
3245      return;
3246 
3247    if (-1 == pop_where_to_insert (m, &where))
3248      return;
3249 
3250    jGtkInsertPopupMenuCmd( insert_popup_menu( m, menu, where ), where );
3251 }
3252 
3253 /************************************
3254 * append_popup_menu_cmd
3255 *
3256 * debug print: "Dest %s, Menu: %s\n", dest, menu
3257 *
3258 ************************************/
3259 
3260 static void
append_popup_menu_cmd(char * dest,char * menu)3261 append_popup_menu_cmd (char *dest, char *menu)
3262 {
3263    Menu_Popup_Type *m;
3264 
3265    /* gtkAppendPopupMenuCmd( dest, menu ); */
3266    m = find_menu_popup (dest);
3267 
3268    if (m == NULL)
3269      return;
3270 
3271    jGtkInsertPopupMenuCmd( insert_popup_menu (m, menu, m->num_subnodes), m->num_subnodes );
3272 }
3273 
3274 /************************************
3275 * insert_separator_cmd
3276 *
3277 * debug print: "Name: %s\n", name
3278 *
3279 ************************************/
3280 
3281 static void
insert_separator_cmd(char * name)3282 insert_separator_cmd (char *name)
3283 {
3284    Menu_Popup_Type *m;
3285    unsigned int where;
3286 
3287    /* gtkInsertSeparatorCmd( name ); */
3288    m = find_menu_popup (name);
3289 
3290    if (m == NULL)
3291      return;
3292 
3293    if (-1 == pop_where_to_insert (m, &where))
3294      return;
3295 
3296    jGtkInsertSeparatorCmd( m, insert_separator( m, where ), where );
3297 }
3298 
3299 /************************************
3300 * append_separator_cmd
3301 *
3302 * debug print: "Name: %s\n", name
3303 *
3304 ************************************/
3305 
3306 static void
append_separator_cmd(char * name)3307 append_separator_cmd (char *name)
3308 {
3309    Menu_Popup_Type *m;
3310 
3311    /* gtkAppendSeparatorCmd( name ); */
3312    m = find_menu_popup (name);
3313 
3314    if (m != NULL)
3315      jGtkInsertSeparatorCmd( m, insert_separator( m, m->num_subnodes ), m->num_subnodes - 1 );
3316 }
3317 
3318 /************************************
3319 * insert_menu_item_cmd_internal
3320 *
3321 * debug print: "Is fun: %d, do append: %d\n", is_fun, do_append
3322 *
3323 ************************************/
3324 
3325 static void
insert_menu_item_cmd_internal(int is_fun,int do_append)3326 insert_menu_item_cmd_internal( int is_fun, int do_append )
3327 {
3328    Menu_Popup_Type *m;
3329    Menu_Node_Type *newItem;
3330    SLang_Name_Type *nt = NULL;
3331    SLang_Any_Type *client_data = NULL;
3332    char *str = NULL;
3333    char *menu = NULL;
3334    char *name = NULL;
3335    unsigned int where;
3336 
3337    /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
3338 
3339    if ( is_fun )
3340      {
3341 	if ( -1 == SLang_pop_anytype( &client_data ) )
3342 	  return;
3343 
3344 	if ( NULL == ( nt = SLang_pop_function() ) )
3345 	  goto free_and_return;
3346      }
3347    else if ( -1 == SLang_pop_slstring( &str ) )
3348      return;
3349 
3350    if ( -1 == SLang_pop_slstring( &name ) )
3351      goto free_and_return;
3352 
3353    if ( -1 == SLang_pop_slstring( &menu ) )
3354      goto free_and_return;
3355 
3356    if ( NULL == ( m = find_menu_popup( menu ) ) )
3357      goto free_and_return;
3358 
3359    if ( do_append )
3360      where = m->num_subnodes;
3361    else if ( -1 == pop_where_to_insert( m, &where ) )
3362      goto free_and_return;
3363 
3364    /* Creates crash because second argument sometimes NULL!!! */
3365    /* Dbp( "Menu: |%s|, Name: |%s|\n", ( menu, name ) ); */
3366 
3367    /* gtkMenuItemNew( menu, name, do_append ); */
3368 
3369    if ( nt != NULL )
3370      {
3371 	newItem = ( Menu_Node_Type * ) insert_slang_fun_item( m, name, nt, client_data, where );
3372 	if ( NULL != newItem )
3373 	  {
3374 	     jGtkMenuItemNew( m, newItem, where );
3375 	     client_data = NULL;
3376 	     nt = NULL;
3377 	  }
3378      }
3379    else
3380      jGtkMenuKeystringItemNew( m, ( Menu_Node_Type * ) insert_keystring_item( m, name, str, where ), where );
3381    /* drop */
3382 
3383 free_and_return:
3384 
3385    if ( client_data != NULL )
3386      SLang_free_anytype( client_data );
3387    SLang_free_slstring( str );
3388    SLang_free_slstring( menu );
3389    SLang_free_slstring( name );
3390 # if SLANG_VERSION > 10400
3391    SLang_free_function( nt );
3392 # endif
3393 }
3394 
3395 /************************************
3396 * insert_menu_item_cmd
3397 *
3398 * debug print: "(void)\n"
3399 *
3400 ************************************/
3401 
3402 static void
insert_menu_item_cmd(void)3403 insert_menu_item_cmd (void)
3404 {
3405    /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
3406    insert_menu_item_cmd_internal( ( SLang_Num_Function_Args == 5 ), 0 );
3407 }
3408 
3409 /************************************
3410 * append_menu_item_cmd
3411 *
3412 * debug print: "(void)\n"
3413 *
3414 ************************************/
3415 
3416 static void
append_menu_item_cmd(void)3417 append_menu_item_cmd (void)
3418 {
3419    /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
3420    insert_menu_item_cmd_internal( ( SLang_Num_Function_Args == 4 ), 1 );
3421 }
3422 
3423 /************************************
3424 * menu_delete_item_cmd
3425 *
3426 * debug print: "Menu: %s\n", menu
3427 *
3428 ************************************/
3429 
3430 static void
menu_delete_item_cmd(char * menu)3431 menu_delete_item_cmd( char *menu )
3432 {
3433    Menu_Popup_Type *parent;
3434    Menu_Node_Type *child;
3435 
3436    /* gtkMenuDeleteItemCmd( menu ); */
3437    parent = (Menu_Popup_Type *)find_menu_node (menu, 1);
3438    child = find_menu_node (menu, 0);
3439    if ((parent == NULL) || (child == NULL))
3440      {
3441 	SLang_verror (SL_INVALID_PARM,
3442 		      "Menu %s does not exist", menu);
3443 	return;
3444      }
3445    menu_delete_node (parent, child);
3446 }
3447 
3448 /************************************
3449 * menu_delete_items_cmd
3450 *
3451 * debug print: "Menu: %s\n", menu
3452 *
3453 ************************************/
3454 
3455 static void
menu_delete_items_cmd(char * menu)3456 menu_delete_items_cmd (char *menu)
3457 {
3458    Menu_Popup_Type *p;
3459 
3460    /* gtkMenuDeleteItemsCmd( menu ); */
3461 
3462    if (NULL == (p = find_menu_popup (menu)))
3463      return;
3464 
3465    menu_delete_nodes (p);
3466 }
3467 
3468 static int
getChildPos(Menu_Popup_Type * parent,Menu_Node_Type * child)3469 getChildPos( Menu_Popup_Type *parent, Menu_Node_Type *child )
3470 {
3471    unsigned int i;
3472 
3473    for ( i = 0; i < parent->num_subnodes; ++i )
3474      {
3475 	if ( parent->subnodes[i] == child ) return( (int) i );
3476      }
3477 
3478    return( -1 );
3479 }
3480 
3481 static void
setObjectAvailable(Menu_Node_Type * parent,Menu_Node_Type * item)3482 setObjectAvailable( Menu_Node_Type *parent, Menu_Node_Type *item )
3483 {
3484    int n;
3485 
3486    if ( parent == item ) return;
3487          /* someone trying to make the menubar unavailable */
3488 
3489    if ( !item->menuItem ) return;
3490 
3491    /* if ( !parent->subMenu ) Return; */
3492 
3493    if ( !gtk_widget_get_parent( item->menuItem ) )
3494      {
3495 	n = getChildPos( ( Menu_Popup_Type * ) parent, item );
3496 	if ( n >= 0 )
3497 	  {
3498 	     gtk_menu_shell_insert( GTK_MENU_SHELL( parent->subMenu ), item->menuItem, n );
3499 	     g_object_unref( item->menuItem );
3500 	  }
3501      }
3502 }
3503 
3504 static void
setObjectUnavailable(Menu_Node_Type * parent,Menu_Node_Type * item)3505 setObjectUnavailable( Menu_Node_Type *parent, Menu_Node_Type *item )
3506 {
3507    GtkWidget *pW;
3508 
3509    if ( parent == item ) return;
3510 
3511    if ( !item->menuItem ) return;
3512 
3513    pW = gtk_widget_get_parent( item->menuItem );
3514    if ( !pW ) return;
3515 
3516    g_object_ref( item->menuItem );
3517 
3518    gtk_container_remove( GTK_CONTAINER( pW ), item->menuItem );
3519 }
3520 
3521 /************************************
3522 * set_object_available_cmd
3523 *
3524 * debug print: "Name: %s, Flag: %d\n", name, flag
3525 *
3526 ************************************/
3527 
set_object_available_cmd(char * name,int * flag)3528 static void set_object_available_cmd (char *name, int *flag)
3529 {
3530    Menu_Node_Type *m;
3531 
3532    gtkSetObjectAvailableCmd( name );
3533 
3534    if (NULL == (m = find_menu_node (name, 0)))
3535      return;
3536 
3537    if ( *flag )
3538      {
3539 	m->flags &= ~MENU_ITEM_UNAVAILABLE;
3540 	setObjectAvailable( find_menu_node( name, 1 ), m );
3541      }
3542    else
3543      {
3544 	m->flags |= MENU_ITEM_UNAVAILABLE;
3545 	setObjectUnavailable( find_menu_node( name, 1 ), m );
3546      }
3547 
3548 }
3549 
3550 /************************************
3551 * pop_popup_callback
3552 *
3553 * debug print: "Menus: %x, type: %d, Names: %x\n", pp, type, ntp
3554 *
3555 ************************************/
3556 
pop_popup_callback(Menu_Popup_Type ** pp,int type,SLang_Name_Type ** ntp)3557 static int pop_popup_callback (Menu_Popup_Type **pp, int type,
3558 			       SLang_Name_Type **ntp)
3559 {
3560    SLang_Name_Type *nt;
3561    char *popup;
3562    Menu_Popup_Type *p;
3563 
3564    if (SLang_peek_at_stack () == SLANG_NULL_TYPE)
3565      {
3566 	(void) SLang_pop_null ();
3567 	nt = NULL;
3568      }
3569    else if (NULL == (nt = SLang_pop_function ()))
3570      return -1;
3571 
3572    if (-1 == SLang_pop_slstring (&popup))
3573      {
3574 # if SLANG_VERSION > 10400
3575 	SLang_free_function (nt);
3576 # endif
3577 	return -1;
3578      }
3579 
3580    p = find_menu_popup (popup);
3581    if (p == NULL)
3582      {
3583 # if SLANG_VERSION > 10400
3584 	SLang_free_function (nt);
3585 # endif
3586 	SLang_free_slstring (popup);
3587 	return -1;
3588      }
3589 
3590    if (type && (p->type != type))
3591      {
3592 	SLang_verror (SL_INVALID_PARM, "%s does not specify the proper menu type", popup);
3593 # if SLANG_VERSION > 10400
3594 	SLang_free_function (nt);
3595 # endif
3596 	SLang_free_slstring (popup);
3597 	return -1;
3598      }
3599 
3600    SLang_free_slstring (popup);
3601 
3602    *ntp = nt;
3603    *pp = p;
3604    return 0;
3605 }
3606 
3607 /************************************
3608 * pop_menubar_callback
3609 *
3610 * debug print: "Menu bar: %x, Name type: %x\n", bp, nt
3611 *
3612 ************************************/
3613 
pop_menubar_callback(Menu_Bar_Type ** bp,SLang_Name_Type ** nt)3614 static int pop_menubar_callback (Menu_Bar_Type **bp, SLang_Name_Type **nt)
3615 {
3616    return pop_popup_callback ((Menu_Popup_Type **)bp, MENU_NODE_MENUBAR, nt);
3617 }
3618 
3619 /************************************
3620 * set_select_menubar_callback
3621 *
3622 * debug print: "(void)\n"
3623 *
3624 ************************************/
3625 
3626 static void
set_select_menubar_callback(void)3627 set_select_menubar_callback (void)
3628 {
3629    Menu_Bar_Type *b;
3630    SLang_Name_Type *nt;
3631 
3632    if (-1 == pop_menubar_callback (&b, &nt))
3633      return;
3634 
3635    b->select_callback = nt;
3636 }
3637 
3638 /************************************
3639 * set_init_menubar_callback
3640 *
3641 * debug print: "(void)\n"
3642 *
3643 ************************************/
3644 
set_init_menubar_callback(void)3645 static void set_init_menubar_callback (void)
3646 {
3647    Menu_Bar_Type *b;
3648    SLang_Name_Type *nt;
3649 
3650    if (-1 == pop_menubar_callback (&b, &nt))
3651      return;
3652 
3653    b->init_callback = nt;
3654 }
3655 
3656 /************************************
3657 * set_select_popup_callback
3658 *
3659 * debug print: "(void)\n"
3660 *
3661 ************************************/
3662 
set_select_popup_callback(void)3663 static void set_select_popup_callback (void)
3664 {
3665    Menu_Popup_Type *p;
3666    SLang_Name_Type *nt;
3667 
3668    if (-1 == pop_popup_callback (&p, MENU_NODE_POPUP, &nt))
3669      return;
3670 
3671    p->select_popup_callback = nt;
3672 }
3673 
3674 /************************************
3675 * set_tweak_popup_callback
3676 *
3677 * debug print: "(void)\n"
3678 *
3679 ************************************/
3680 
set_tweak_popup_callback(void)3681 static void set_tweak_popup_callback (void)
3682 {
3683    Menu_Popup_Type *p;
3684    SLang_Name_Type *nt;
3685 
3686    if (-1 == pop_popup_callback (&p, MENU_NODE_POPUP, &nt))
3687      return;
3688 
3689    p->tweak_popup_callback = nt;
3690 }
3691 
3692 /************************************
3693 * copy_menu_cmd
3694 *
3695 * debug print: "Dest: %s, Src: %s\n", destname, srcname
3696 *
3697 ************************************/
3698 
3699 static void
copy_menu_cmd(char * destname,char * srcname)3700 copy_menu_cmd (char *destname, char *srcname)
3701 {
3702    Menu_Popup_Type *dest;
3703    Menu_Node_Type *src;
3704 
3705    dest = find_menu_popup (destname);
3706    if (dest == NULL)
3707      return;
3708 
3709    src = find_menu_node (srcname, 0);
3710    if (src == NULL)
3711      return;
3712 
3713    /* (void) copy_menu (dest, src); */
3714    gtkCopyMenu( dest, src );
3715 }
3716 
3717 /************************************
3718 * set_menu_bar_prefix_string
3719 *
3720 * debug print: "Menubar: |%s|, s: |%s|\n", menubar, s
3721 *
3722 ************************************/
3723 
3724 static void
set_menu_bar_prefix_string(char * menubar,char * s)3725 set_menu_bar_prefix_string (char *menubar, char *s)
3726 {
3727    Menu_Bar_Type *b;
3728 
3729    if (NULL == (b = menu_find_menu_bar (menubar, 1)))
3730      return;
3731 
3732    s = SLang_create_slstring (s);
3733    if (s == NULL)
3734      return;
3735 
3736    SLang_free_slstring (b->prefix_string);
3737    b->prefix_string = s;
3738 }
3739 
3740 /************************************
3741 * execTBCmd
3742 *
3743 * debug print: "Menu: %s\n", menu
3744 *
3745 ************************************/
3746 
3747 void
execTBCmd(char * menu)3748 execTBCmd( char *menu )
3749 {
3750    char *menuMax;
3751    char *popup;
3752    Menu_Popup_Type *activePopup;
3753    char *savMenu = SLmalloc( strlen( menu ) + 1 );
3754    Menu_Bar_Type *savBar = NULL;
3755    Menu_Bar_Type *b = Menu_Bar_Root;
3756 
3757    if (savMenu == NULL)
3758      return;
3759 
3760    strcpy( savMenu, menu );
3761 
3762    /* Dbp1( "menu: %s\n", menu ); */
3763 
3764    menuMax = strchr( menu, '.' );
3765    if ( menuMax == NULL )
3766      menuMax = menu + strlen( menu );
3767 
3768    while ( b != NULL )
3769      {
3770       /* Dbp1( "menuBarName: %s\n", b->name ); */
3771 	if ( menu_name_eqs( b->name, menu, menuMax ) )
3772 	  {
3773 	     savBar = b;
3774 	     b = NULL;
3775 	  }
3776 	else
3777 	  b = b->next;
3778      }
3779 
3780    /* (void) jed_exit_menu_bar (); */
3781    /* if (-1 == jed_select_menu_bar ()) */
3782    /*   Return; */
3783 
3784    if ( !savBar )
3785      {
3786       /* printf( "Cannot find menuBar: %s\n", menu ); */
3787 	return;
3788      }
3789 
3790    activePopup = ( Menu_Popup_Type * ) savBar;
3791 
3792    if (NULL == (menu = SLmake_string (menu)))
3793      return;
3794 
3795    /* for now ignore the menubar name and use default */
3796    popup = strchr (menu, '.');
3797    if (popup != NULL)
3798      popup++;
3799 
3800    while ((popup != NULL) && (activePopup != NULL))
3801      {
3802 	Menu_Node_Type *m;
3803 	char *next_popup;
3804 
3805 	/* Dbp1( "next_popup: %s\n", next_popup ); */
3806 
3807 	next_popup = strchr (popup, '.');
3808 
3809 	/* Dbp1( "next_popup: %s\n", next_popup ); */
3810 
3811 	if (next_popup != NULL)
3812 	  *next_popup++ = 0;
3813 
3814 	/* Dbp1( "next_popup: %s\n", next_popup ); */
3815 	/* Dbp1( "popup:      %s\n", popup ); */
3816         /* Dbp1( "Active_Popup-name: %s\n", activePopup->name ); */
3817 
3818 	if ( NULL == ( m = find_subnode( activePopup, popup ) ) )
3819 	  {
3820 	     SLang_verror( SL_INVALID_PARM,
3821 			   "Unable to find a popup menu called %s", menu );
3822 	     break;
3823 	  }
3824 	/* set_node_selection( activePopup, m ); */
3825 	if ( -1 == execMenuTbCmd( m ) )
3826 	  break;
3827 
3828 	popup = next_popup;
3829      }
3830 
3831    SLfree( menu );
3832 }
3833 
3834 static Menu_Node_Type *
getMenuNodeByPath(char * menu)3835 getMenuNodeByPath( char *menu )
3836 {
3837    char *menuMax;
3838    char *popup;
3839    Menu_Popup_Type *activePopup;
3840    Menu_Popup_Type *p;
3841    /* char *savMenu = SLmalloc( strlen( menu ) + 1 ); */
3842    Menu_Bar_Type *savBar = NULL;
3843    Menu_Bar_Type *b = Menu_Bar_Root;
3844 
3845    /* strcpy( savMenu, menu ); */
3846 
3847    /* Dbp1( "menu: %s\n", menu ); */
3848 
3849    menuMax = strchr( menu, '.' );
3850    if ( menuMax == NULL )
3851      menuMax = menu + strlen( menu );
3852 
3853    while ( b != NULL )
3854      {
3855       /* Dbp1( "menuBarName: %s\n", b->name ); */
3856 	if ( menu_name_eqs( b->name, menu, menuMax ) )
3857 	  {
3858 	     savBar = b;
3859 	     b = NULL;
3860 	  }
3861 	else
3862 	  b = b->next;
3863      }
3864 
3865    /* (void) jed_exit_menu_bar (); */
3866    /* if (-1 == jed_select_menu_bar ()) */
3867    /*   Return; */
3868 
3869    if ( !savBar )
3870      {
3871       /* printf( "Cannot find menuBar: %s\n", menu ); */
3872       /* SLfree( savMenu ); */
3873 	return( NULL );
3874      }
3875 
3876    activePopup = ( Menu_Popup_Type * ) savBar;
3877 
3878    if (NULL == (menu = SLmake_string (menu)))
3879      return( NULL );
3880 
3881    /* for now ignore the menubar name and use default */
3882    popup = strchr (menu, '.');
3883    if (popup != NULL)
3884      popup++;
3885 
3886    while ((popup != NULL) && (activePopup != NULL))
3887      {
3888 	Menu_Node_Type *m;
3889 	char *next_popup;
3890 
3891 	/* Dbp1( "next_popup: %s\n", next_popup ); */
3892 
3893 	next_popup = strchr (popup, '.');
3894 
3895 	/* Dbp1( "next_popup: %s\n", next_popup ); */
3896 
3897 	if (next_popup != NULL)
3898 	  *next_popup++ = 0;
3899 
3900 	/* Dbp1( "next_popup: %s\n", next_popup ); */
3901 	/* Dbp1( "popup:      %s\n", popup ); */
3902         /* Dbp1( "Active_Popup-name: %s\n", activePopup->name ); */
3903 
3904 	if ( NULL == ( m = find_subnode( activePopup, popup ) ) )
3905 	  {
3906 	     SLang_verror( SL_INVALID_PARM,
3907 			   "Unable to find a popup menu called %s", menu );
3908 	     break;
3909 	  }
3910 	/* set_node_selection( activePopup, m ); */
3911 	/* if ( -1 == execMenuTbCmd( m ) ) */
3912 	/*   break; */
3913 
3914         if ( m->type == MENU_NODE_POPUP )
3915 	  {
3916 	     p = ( Menu_Popup_Type * ) m;
3917 	     if ( -1 == prepare_popup( p ) )
3918 	       {
3919 		  break;
3920 	       }
3921 	     Active_Popup = p;
3922 	     select_next_active_node( p, p->num_subnodes, 0 );
3923 	  }
3924         else
3925 	  {
3926 	     return( m );
3927 	  }
3928 
3929 	popup = next_popup;
3930      }
3931 
3932    SLfree( menu );
3933    /* SLfree( savMenu ); */
3934    return( NULL );
3935 }
3936 
3937 /************************************
3938 * popup_menu_cmd
3939 *
3940 * debug print: "Menu: |%s|\n", menu
3941 *
3942 ************************************/
3943 
popup_menu_cmd(char * menu)3944 static void popup_menu_cmd (char *menu)
3945 {
3946    char *popup;
3947 
3948    /* printf( "File: %s, Line: %d: menu: %s\n", __FILE__, __LINE__, menu ); */
3949 
3950    (void) jed_exit_menu_bar ();
3951    if (-1 == jed_select_menu_bar ())
3952      return;
3953 
3954    if (NULL == (menu = SLmake_string (menu)))
3955      return;
3956 
3957    /* for now ignore the menubar name and use default */
3958    popup = strchr (menu, '.');
3959    if (popup != NULL)
3960      popup++;
3961 
3962    while ((popup != NULL) && (Active_Popup != NULL))
3963      {
3964 	Menu_Node_Type *m;
3965 	char *next_popup;
3966 
3967       /* printf( "File: %s, Line: %d: next_popup: %s\n", __FILE__, __LINE__, next_popup ); */
3968 
3969 	next_popup = strchr (popup, '.');
3970 
3971       /* printf( "File: %s, Line: %d: next_popup: %s\n", __FILE__, __LINE__, next_popup ); */
3972 
3973 	if (next_popup != NULL)
3974 	  *next_popup++ = 0;
3975 
3976       /* printf( "File: %s, Line: %d: next_popup: %s\n", __FILE__, __LINE__, next_popup ); */
3977       /* printf( "File: %s, Line: %d: popup:      %s\n", __FILE__, __LINE__, popup ); */
3978       /* printf( "File: %s, Line: %d: Active_Popup-name: %s\n", __FILE__, __LINE__, Active_Popup->name ); */
3979 
3980 	if (NULL == (m = find_subnode (Active_Popup, popup)))
3981 	  {
3982 	     SLang_verror (SL_INVALID_PARM,
3983 			   "Unable to find a popup menu called %s", menu);
3984 	     break;
3985 	  }
3986 	set_node_selection (Active_Popup, m);
3987 	if (-1 == select_menu_cmd ())
3988 	  break;
3989 
3990 	popup = next_popup;
3991      }
3992 
3993    SLfree (menu);
3994 }
3995 
3996 /************************************
3997 * insertToolbarItemCmdInternal
3998 *
3999 * debug print: "Is fun, %d, do append: %d, isStopck: %d\n", is_fun, do_append, isStock
4000 *
4001 ************************************/
4002 
4003 static void
insertToolbarItemCmdInternal(int is_fun,int do_append,int isStock)4004 insertToolbarItemCmdInternal( int is_fun, int do_append, int isStock )
4005 {
4006    Menu_Popup_Type *m;
4007    Menu_Node_Type *nn; /* new node */
4008    SLang_Name_Type *nt = NULL;
4009    SLang_Any_Type *client_data = NULL;
4010    char *keySeq = NULL;
4011    char *specCmd = NULL;
4012    char *str = NULL;
4013    char *menu = NULL;
4014    char *name = NULL;
4015    char *iconName = NULL;
4016    unsigned int where;
4017 
4018    /* printf( "File: %s, Line: %d\n", __FILE__, __LINE__ ); */
4019 
4020    if ( is_fun == 2 )
4021      {
4022 	if ( SLang_Num_Function_Args == 5 )
4023 	  {
4024 	     if ( -1 == SLang_pop_slstring( &keySeq ) )
4025 	       {
4026 		  return;
4027 	       }
4028 	     if ( -1 == SLang_pop_slstring( &specCmd ) )
4029 	       goto free_and_return;
4030 	 /* printf( "FILE: %s, Line: %d: keySeq: %s, specCmd: %s\n", __FILE__, __LINE__, keySeq, specCmd ); */
4031 	  }
4032 	else if ( -1 == SLang_pop_slstring( &specCmd ) )
4033 	  {
4034 	 /* printf( "FILE: %s, Line: %d: specCmd: %s\n", __FILE__, __LINE__, specCmd ); */
4035 	     return;
4036 	  }
4037      }
4038    else
4039      {
4040 	if ( is_fun )
4041 	  {
4042 	     if ( -1 == SLang_pop_anytype( &client_data ) )
4043 	       return;
4044 
4045 	     if ( NULL == ( nt = SLang_pop_function() ) )
4046 	       goto free_and_return;
4047 	  }
4048 	else if ( -1 == SLang_pop_slstring( &str ) )
4049 	  return;
4050      }
4051 
4052    if ( -1 == SLang_pop_slstring( &iconName ) )
4053      goto free_and_return;
4054 
4055    if ( -1 == SLang_pop_slstring( &name ) )
4056      goto free_and_return;
4057 
4058    if ( -1 == SLang_pop_slstring( &menu ) )
4059      goto free_and_return;
4060 
4061    /* printf( "FILE: %s, Line: %d: menu: %s\n", __FILE__, __LINE__, menu ); */
4062    /* printf( "FILE: %s, Line: %d: name: %s\n", __FILE__, __LINE__, name ); */
4063    /* printf( "FILE: %s, Line: %d: iconName: %s\n", __FILE__, __LINE__, iconName ); */
4064 
4065    if ( NULL == ( m = find_menu_popup( menu ) ) )
4066      goto free_and_return;
4067 
4068    /* Dbp1( "m: %x\n", m ); */
4069 
4070    if ( do_append )
4071      where = m->num_subnodes;
4072    else if ( -1 == pop_where_to_insert( m, &where ) )
4073      goto free_and_return;
4074 
4075    if ( where > m->num_subnodes || do_append )
4076      {
4077 	where = -1;
4078      }
4079 
4080    if ( is_fun == 2 )
4081      {
4082 	nn = ( Menu_Node_Type * ) insertSpecCmdItem( m, name, specCmd, keySeq, where );
4083      }
4084    else
4085      {
4086 	if ( nt != NULL )
4087 	  {
4088 	     if ( NULL != ( nn = ( Menu_Node_Type * ) insert_slang_fun_item( m, name, nt, client_data, where ) ) )
4089 	       {
4090 		  client_data = NULL;
4091 		  nt = NULL;
4092 	       }
4093 	  }
4094 	else
4095 	  nn = ( Menu_Node_Type * ) insert_keystring_item( m, name, str, where );
4096    /* drop */
4097      }
4098 
4099    if ( isStock )
4100      {
4101 	gtkToolbarStockItemNew( m, nn, iconName, where );
4102      }
4103    else
4104      {
4105 	gtkToolbarItemNew( m, nn, iconName, where );
4106      }
4107 
4108 free_and_return:
4109 
4110    if ( client_data != NULL )
4111      SLang_free_anytype( client_data );
4112    SLang_free_slstring( keySeq );
4113    SLang_free_slstring( specCmd );
4114    SLang_free_slstring( str );
4115    SLang_free_slstring( menu );
4116    SLang_free_slstring( name );
4117    SLang_free_slstring( iconName );
4118 # if SLANG_VERSION > 10400
4119    SLang_free_function( nt );
4120 # endif
4121 }
4122 
4123 static void
toolbarExtension(void)4124 toolbarExtension(void)
4125 {
4126    /* Do nothing. Only to allow to check, whether toolbars can be used!!! */
4127 }
4128 
4129 /************************************
4130 * createToolbarCmd
4131 *
4132 * debug print: "Name: %s\n", name
4133 *
4134 ************************************/
4135 
4136 static void
createToolbarCmd(char * name)4137 createToolbarCmd( char *name )
4138 {
4139    /* printf( "File: %s, Line: %d: Function(%s): create_tool_bar_cmd\n", __FILE__, __LINE__, name ); */
4140    /* gtkCreateToolbarCmd( name ); */
4141    gtkCreateToolbarCmd( create_menu_bar( name, 10 ) );
4142    /* ( void ) create_menu_bar( name, 10 ); */
4143 }
4144 
4145 /************************************
4146 * addBufferToolbarCmd
4147 *
4148 * debug print: "Name: %s\n", name
4149 *
4150 ************************************/
4151 
4152 static void
addBufferToolbarCmd(char * name)4153 addBufferToolbarCmd( char *name )
4154 {
4155    /* printf( "File: %s, Line: %d: Funktion(%s): add_buffer_tool_bar_cmd\n", __FILE__, __LINE__, name ); */
4156    gtkAddBufferToolbarCmd( name );
4157 }
4158 
4159 /************************************
4160 * insertToolbarItemCmd
4161 *
4162 * debug print: "(void)\n"
4163 *
4164 ************************************/
4165 
4166 static void
insertToolbarItemCmd(void)4167 insertToolbarItemCmd( void )
4168 {
4169    /* printf( "File: %s, Line: %d: append_tool_bar_item_cmd\n", __FILE__, __LINE__ ); */
4170    insertToolbarItemCmdInternal( ( SLang_Num_Function_Args == 6 ), 0, 0 );
4171 }
4172 
4173 /************************************
4174 * insertToolbarStockItemCmd
4175 *
4176 * debug print: "(void)\n"
4177 *
4178 ************************************/
4179 
4180 static void
insertToolbarStockItemCmd(void)4181 insertToolbarStockItemCmd( void )
4182 {
4183    /* printf( "File: %s, Line: %d: append_tool_bar_item_cmd\n", __FILE__, __LINE__ ); */
4184    insertToolbarItemCmdInternal( ( SLang_Num_Function_Args == 6 ), 0, 1 );
4185 }
4186 
4187 /************************************
4188 * insertToolbarSpecialCmd
4189 *
4190 * debug print: "(void)\n"
4191 *
4192 ************************************/
4193 
4194 static void
insertToolbarSpecialCmd(void)4195 insertToolbarSpecialCmd( void )
4196 {
4197    /* printf( "File: %s, Line: %d: Funktion: append_tool_bar_special_cmd\n", __FILE__, __LINE__ ); */
4198    insertToolbarItemCmdInternal( 2, 0, 0 );
4199 }
4200 
4201 /************************************
4202 * insertToolbarStockSpecialCmd
4203 *
4204 * debug print: "(void)\n"
4205 *
4206 ************************************/
4207 
4208 static void
insertToolbarStockSpecialCmd(void)4209 insertToolbarStockSpecialCmd( void )
4210 {
4211    /* printf( "File: %s, Line: %d: Funktion: append_tool_bar_stock_special_cmd\n", __FILE__, __LINE__ ); */
4212    insertToolbarItemCmdInternal( 2, 0, 1 );
4213 }
4214 
4215 /************************************
4216 * appendToolbarStockItemCmd
4217 *
4218 * debug print: "(void)\n"
4219 *
4220 ************************************/
4221 
4222 static void
appendToolbarItemCmd(void)4223 appendToolbarItemCmd( void )
4224 {
4225    /* printf( "File: %s, Line: %d: append_tool_bar_item_cmd\n", __FILE__, __LINE__ ); */
4226    insertToolbarItemCmdInternal( ( SLang_Num_Function_Args == 5 ), 1, 0 );
4227 }
4228 
4229 /************************************
4230 * appendToolbarStockItemCmd
4231 *
4232 * debug print: "(void)\n"
4233 *
4234 ************************************/
4235 
4236 static void
appendToolbarStockItemCmd(void)4237 appendToolbarStockItemCmd( void )
4238 {
4239    /* printf( "File: %s, Line: %d: Funktion(%s): append_tool_bar_stock_item_cmd\n", __FILE__, __LINE__ ); */
4240    insertToolbarItemCmdInternal( ( SLang_Num_Function_Args == 5 ), 1, 1 );
4241 }
4242 
4243 /************************************
4244 * appendToolbarSpecialCmd
4245 *
4246 * debug print: "(void)\n"
4247 *
4248 ************************************/
4249 
4250 static void
appendToolbarSpecialCmd(void)4251 appendToolbarSpecialCmd( void )
4252 {
4253    /* printf( "File: %s, Line: %d: Funktion: append_tool_bar_special_cmd\n", __FILE__, __LINE__ ); */
4254    insertToolbarItemCmdInternal( 2, 1, 0 );
4255 }
4256 
4257 /************************************
4258 * appendToolbarStockSpecialCmd
4259 *
4260 * debug print: "(void)\n"
4261 *
4262 ************************************/
4263 
4264 static void
appendToolbarStockSpecialCmd(void)4265 appendToolbarStockSpecialCmd( void )
4266 {
4267    /* printf( "File: %s, Line: %d: Funktion: append_tool_bar_stock_special_cmd\n", __FILE__, __LINE__ ); */
4268    insertToolbarItemCmdInternal( 2, 1, 1 );
4269 }
4270 
4271 /************************************
4272 * appendToolbarSeparatorItemCmd
4273 *
4274 * debug print: "Name: %s\n", name
4275 *
4276 ************************************/
4277 
4278 static void
appendToolbarSeparatorItemCmd(char * name)4279 appendToolbarSeparatorItemCmd( char *name )
4280 {
4281    Menu_Popup_Type *m;
4282 
4283    /* gtkToolbarAppendSeparatorCmd( name ); */
4284    m = find_menu_popup (name);
4285 
4286    if (m != NULL)
4287      gtkToolbarAppendSeparatorCmd( m, insert_separator( m, m->num_subnodes ) );
4288 }
4289 
4290 /************************************
4291 * insertToolbarSeparatorItemCmd
4292 *
4293 * debug print: "Name: %s\n", name
4294 *
4295 ************************************/
4296 
4297 static void
insertToolbarSeparatorItemCmd(char * name)4298 insertToolbarSeparatorItemCmd( char *name )
4299 {
4300    unsigned int where;
4301    Menu_Popup_Type *m;
4302 
4303    /* gtkToolbarAppendSeparatorCmd( name ); */
4304    m = find_menu_popup (name);
4305 
4306    if ( m == NULL )
4307      return;
4308 
4309    if (-1 == pop_where_to_insert( m, &where ))
4310      return;
4311 
4312    if ( where > m->num_subnodes ) where = m->num_subnodes;
4313 
4314    gtkToolbarInsertSeparatorCmd( m, insert_separator( m, where ), where );
4315 }
4316 
4317 /************************************
4318 * toolbarGetNumItemsCmd
4319 *
4320 * debug print: "Menu: %s\n", menu
4321 *
4322 ************************************/
4323 
4324 static int
toolbarGetNumItemsCmd(char * menu)4325 toolbarGetNumItemsCmd( char *menu )
4326 {
4327    Menu_Popup_Type *p;
4328 
4329    /* gtkMenuDeleteItemsCmd( menu ); */
4330 
4331    if (NULL == (p = find_menu_popup (menu)))
4332      return( - 1 );
4333 
4334    if ( p->type != MENU_NODE_POPUP &&
4335 	p->type != MENU_NODE_MENUBAR )
4336      {
4337 	return( -1 );
4338      }
4339 
4340    return( p->num_subnodes );
4341 }
4342 
4343 static SLang_Intrin_Fun_Type Menu_Table[] =
4344 {
4345 
4346    /****************************************************************************************************/
4347    /***** Menu functions       *************************************************************************/
4348    /****************************************************************************************************/
4349    MAKE_INTRINSIC_S(  "menu_create_menu_bar", create_menu_bar_cmd, VOID_TYPE ),
4350    MAKE_INTRINSIC_SS( "menu_append_popup", append_popup_menu_cmd, VOID_TYPE ),
4351    MAKE_INTRINSIC_SS( "menu_insert_popup", insert_popup_menu_cmd, VOID_TYPE ),
4352    MAKE_INTRINSIC_S(  "menu_use_menu_bar", set_buffer_menu_bar_cmd, VOID_TYPE ),
4353    MAKE_INTRINSIC_S(  "menu_append_separator", append_separator_cmd, VOID_TYPE ),
4354    MAKE_INTRINSIC_S(  "menu_insert_separator", insert_separator_cmd, VOID_TYPE ),
4355    MAKE_INTRINSIC_0(  "menu_append_item", append_menu_item_cmd, VOID_TYPE ),
4356    MAKE_INTRINSIC_0(  "menu_insert_item", insert_menu_item_cmd, VOID_TYPE ),
4357    MAKE_INTRINSIC_S(  "menu_delete_item", menu_delete_item_cmd, VOID_TYPE ),
4358    MAKE_INTRINSIC_S(  "menu_delete_items", menu_delete_items_cmd, VOID_TYPE ),
4359    MAKE_INTRINSIC_SI( "menu_set_object_available", set_object_available_cmd, VOID_TYPE ),
4360    MAKE_INTRINSIC_0(  "menu_set_select_menubar_callback", set_select_menubar_callback, VOID_TYPE ),
4361    MAKE_INTRINSIC_0(  "menu_set_init_menubar_callback", set_init_menubar_callback, VOID_TYPE ),
4362    MAKE_INTRINSIC_0(  "menu_set_select_popup_callback", set_select_popup_callback, VOID_TYPE ),
4363    MAKE_INTRINSIC_0(  "menu_set_tweak_popup_callback", set_tweak_popup_callback, VOID_TYPE ),
4364    MAKE_INTRINSIC_SS( "menu_copy_menu", copy_menu_cmd, VOID_TYPE ),
4365    MAKE_INTRINSIC_SS( "menu_set_menu_bar_prefix", set_menu_bar_prefix_string, VOID_TYPE ),
4366    MAKE_INTRINSIC_S(  "menu_select_menu", popup_menu_cmd, VOID_TYPE ),
4367 
4368    /****************************************************************************************************/
4369    /***** Toolbar functions    *************************************************************************/
4370    /****************************************************************************************************/
4371 
4372    MAKE_INTRINSIC_0(  "toolbar_extension", toolbarExtension, VOID_TYPE ),
4373 
4374    /* MAKE_INTRINSIC_S(  "toolbar_create_toolbar", createToolbarCmd, VOID_TYPE ), */
4375    MAKE_INTRINSIC_S(  "toolbar_create", createToolbarCmd, VOID_TYPE ),
4376    /* MAKE_INTRINSIC_S(  "toolbar_add_toolbar", addBufferToolbarCmd, VOID_TYPE ), */
4377    /* MAKE_INTRINSIC_S(  "toolbar_append_toolbar", addBufferToolbarCmd, VOID_TYPE ), */
4378    MAKE_INTRINSIC_S(  "toolbar_append", addBufferToolbarCmd, VOID_TYPE ),
4379    /* MAKE_INTRINSIC_SI( "toolbar_insert_toolbar", jGtkInsertBufferToolbarCmd, VOID_TYPE ), */
4380    MAKE_INTRINSIC_SI( "toolbar_insert", jGtkInsertBufferToolbarCmd, VOID_TYPE ),
4381    /* MAKE_INTRINSIC_SI( "toolbar_detach", ???, VOID_TYPE ), */
4382 
4383    MAKE_INTRINSIC_0(  "toolbar_append_item", appendToolbarItemCmd, VOID_TYPE ),
4384    MAKE_INTRINSIC_0(  "toolbar_append_stock_item", appendToolbarStockItemCmd, VOID_TYPE ),
4385    MAKE_INTRINSIC_S(  "toolbar_append_separator", appendToolbarSeparatorItemCmd, VOID_TYPE ),
4386    MAKE_INTRINSIC_0(  "toolbar_append_stock_spec", appendToolbarStockSpecialCmd, VOID_TYPE ),
4387    MAKE_INTRINSIC_0(  "toolbar_append_spec", appendToolbarSpecialCmd, VOID_TYPE ),
4388 
4389    MAKE_INTRINSIC_0(  "toolbar_insert_item", insertToolbarItemCmd, VOID_TYPE ),
4390    MAKE_INTRINSIC_0(  "toolbar_insert_stock_item", insertToolbarStockItemCmd, VOID_TYPE ),
4391    MAKE_INTRINSIC_S(  "toolbar_insert_separator", insertToolbarSeparatorItemCmd, VOID_TYPE ),
4392    MAKE_INTRINSIC_0(  "toolbar_insert_stock_spec", insertToolbarStockSpecialCmd, VOID_TYPE ),
4393    MAKE_INTRINSIC_0(  "toolbar_insert_spec", insertToolbarSpecialCmd, VOID_TYPE ),
4394 
4395    MAKE_INTRINSIC_S(  "toolbar_delete_items", menu_delete_items_cmd, VOID_TYPE ),
4396    MAKE_INTRINSIC_S(  "toolbar_delete_item", menu_delete_item_cmd, VOID_TYPE ),
4397 
4398    MAKE_INTRINSIC_S(  "toolbar_get_num_items", toolbarGetNumItemsCmd, INT_TYPE ),
4399 
4400    MAKE_INTRINSIC( NULL, NULL, 0, 0 )
4401 };
4402 
4403 /************************************
4404 * jGtkDestroyWidget
4405 *
4406 * debug print: "w: %x, data: %x, *data: %x\n", w, data, *data
4407 *
4408 ************************************/
4409 
4410 static void
jGtkDestroyWidget(GtkWidget * w,gpointer data)4411 jGtkDestroyWidget( GtkWidget *w, gpointer data )
4412 {
4413    GtkWidget **wp = ( GtkWidget ** ) data;
4414 
4415    *wp = NULL;
4416 }
4417 
4418 /************************************
4419 * jed_init_menus
4420 *
4421 * debug print: "(void)\n"
4422 *
4423 ************************************/
4424 
jed_init_menus(void)4425 int jed_init_menus (void)
4426 {
4427    if (-1 == init_menu_keymap ())
4428      return -1;
4429 
4430    if (-1 == SLadd_intrin_fun_table (Menu_Table, NULL))
4431      return -1;
4432 # if 0
4433    if (-1 == make_global_menubar ())
4434      return -1;
4435 # endif
4436    return 0;
4437 }
4438 
4439 /********************************************************************
4440  ********************************************************************
4441  *****     Menu functions
4442  *******************************************************************
4443  *******************************************************************/
4444 
4445 /* extern void        popup_menu_cmd( char * ); */
4446 
4447 void
jgtk_initMenubarStruct(void)4448 jgtk_initMenubarStruct(void)
4449 {
4450    if ( Global_Menu_Bar )
4451      {
4452 	set_buffer_menu_bar_cmd( "Global" );
4453      }
4454 }
4455 
4456 # if 0
4457 
4458 static int
4459 checkMenuPathExists( char *dest, char *name )
4460 {
4461    char *newPath = SLmalloc( strlen( dest ) + 1 + strlen( name ) + 1 );
4462    char *savPath = newPath;
4463 
4464    if (newPath == NULL)
4465      return -1;
4466 
4467    strcpy( newPath, dest );
4468    newPath += strlen( dest );
4469 
4470    *newPath = '.';
4471    newPath += 1;
4472 
4473    strcpy( newPath, name );
4474 
4475    if ( g_hash_table_lookup( menuArray, savPath ) )
4476      {
4477 	SLfree( savPath );
4478 	return( 1 );
4479      }
4480    else
4481      {
4482 	SLfree( savPath );
4483 	return( 0 );
4484      }
4485 }
4486 
4487 char *
4488 addNewMenuPath( char *dest, char *name, GtkJedMenuType *menu )
4489 {
4490    char *newPath = SLmalloc( strlen( dest ) + 1 + strlen( name ) + 1 );
4491    char *savPath = newPath;
4492 
4493    if (newPath == NULL)
4494      return NULL;
4495 
4496    strcpy( newPath, dest );
4497    newPath += strlen( dest );
4498 
4499    *newPath = '.';
4500    newPath += 1;
4501 
4502    strcpy( newPath, name );
4503 
4504    g_hash_table_insert( menuArray, savPath, menu );
4505 
4506    return( savPath );
4507 }
4508 
4509 # endif
4510 
4511 static int
isMnemonic(char * name)4512 isMnemonic( char *name )
4513 {
4514    while ( *name )
4515      {
4516 	if ( *name == '&' )
4517 	  {
4518 	     return( True );
4519 	  }
4520 	++name;
4521      }
4522    return( False );
4523 }
4524 
4525 static char *
createMenuNameMnemonic(char * name)4526 createMenuNameMnemonic( char *name )
4527 {
4528    char *savName;
4529    char *gtkName = SLmalloc( strlen( name ) + 1 );
4530    int notEnd;
4531 
4532    if (gtkName == NULL)
4533      return NULL;
4534 
4535    strcpy( gtkName, name );
4536 
4537    savName = gtkName;
4538 
4539    notEnd = 1;
4540 
4541    while( *savName && notEnd )
4542      {
4543 	if ( *savName == '&' )
4544 	  {
4545 	     *savName = '_';
4546 	     notEnd = 0;
4547 	  }
4548 	++savName;
4549      }
4550 
4551    return( gtkName );
4552 }
4553 
4554 gboolean
menuBarActivateCurrentCB(GtkWidget * w,GdkEvent * ev,gpointer * data)4555 menuBarActivateCurrentCB( GtkWidget *w,
4556 			  GdkEvent  *ev,
4557 			  gpointer  *data )
4558 {
4559 /*    printf( "Current Menubar activated!!!!!!!!!!!!!\n" ); */
4560    /* Db; */
4561    /* Return( FALSE ); */
4562    jed_select_menu_bar();
4563    Jed_Menus_Active = 0;
4564 
4565    return( FALSE );
4566 }
4567 
4568 /************************************
4569 * jGtkGetKeystring
4570 *
4571 * debug print: "Menu keystring fun type: %x, color0: %d, color1: %d, field_widht: %d\n", k, color0, color1, field_width
4572 *
4573 ************************************/
4574 
4575 static int
jGtkGetKeystring(Menu_Keystring_Fun_Type * k,char * retBuf)4576 jGtkGetKeystring( Menu_Keystring_Fun_Type *k, char *retBuf )
4577 {
4578    int i;
4579    SLang_Key_Type *key, *key_root;
4580    FVOID_STAR fp;
4581    unsigned char type;
4582    char buf[3];
4583    unsigned int best_len;
4584    char *best_keystring;
4585    SLang_Key_Type *best_key;
4586    char *name;
4587 
4588    /* draw_name (k->name, color0, color1, field_width); */
4589 
4590    name = k->keystring;
4591    /* Now try to draw the binding */
4592 
4593    if (NULL == (fp = (FVOID_STAR) SLang_find_key_function(name, CBuf->keymap)))
4594      type = SLKEY_F_INTERPRET;
4595    else type = SLKEY_F_INTRINSIC;
4596 
4597    best_keystring = NULL;
4598    best_len = 0xFFFF;
4599    best_key = NULL;
4600 
4601    key_root = CBuf->keymap->keymap;
4602 
4603    for (i = 0; i < 256; i++, key_root++)
4604      {
4605 # ifdef IBMPC_SYSTEM
4606 	if ((i == 0) || (i == 0xE0))
4607 	  continue;
4608 # endif
4609 
4610 	key = key_root->next;
4611 	if ((key == NULL) && (type == key_root->type))
4612 	  {
4613 	     if (type == SLKEY_F_INTERPRET)
4614 	       {
4615 		  if (strcmp (name, key_root->f.s))
4616 		    continue;
4617 	       }
4618 	     else if ((type != SLKEY_F_INTRINSIC) || (fp != key_root->f.f))
4619 	       continue;
4620 
4621 	     buf[0] = i;
4622 	     buf[1] = 0;
4623 # ifndef IBMPC_SYSTEM
4624 	     if (i == 0)
4625 	       {
4626 		  buf[0] = '^';
4627 		  buf[1] = '@';
4628 		  buf[2] = 0;
4629 	       }
4630 # endif
4631 	     best_keystring = buf;
4632 	     break;
4633 	  }
4634 
4635 	while (key != NULL)
4636 	  {
4637 	     char *s;
4638 	     SLang_Key_Type *this_key = key;
4639 
4640 	     key = key->next;
4641 
4642 	     if (this_key->type != type)
4643 	       continue;
4644 
4645 	     if (type == SLKEY_F_INTERPRET)
4646 	       {
4647 		  if (strcmp (name, this_key->f.s))
4648 		    continue;
4649 	       }
4650 	     else if ((type != SLKEY_F_INTRINSIC) || (fp != this_key->f.f))
4651 	       continue;
4652 
4653 	     s = SLang_make_keystring (this_key->str);
4654 	     if (s == NULL)
4655 	       continue;
4656 
4657 	     if (strlen (s) < best_len)
4658 	       {
4659 		  best_key = this_key;
4660 		  best_len = strlen (s);
4661 	       }
4662 	  }
4663      }
4664 
4665    /* Dbp2( "Best keystring: %x, Best key: %x\n", best_keystring, best_key ); */
4666 
4667    if ( best_keystring && *best_keystring > 0 && *best_keystring < 32 )
4668      {
4669 	best_keystring[2] = '\0';
4670 	best_keystring[1] = *best_keystring + 64;
4671 	best_keystring[0] = '^';
4672      }
4673 
4674    if ((best_keystring != NULL)
4675        && ((*best_keystring & 0x80) || ((unsigned char)*best_keystring < 32)))
4676      best_keystring = NULL;
4677 
4678    if (best_keystring == NULL)
4679      {
4680       /* Db; */
4681 	if (best_key == NULL)
4682 	  return 0;
4683 
4684         /* Db; */
4685 	best_keystring = SLang_make_keystring (best_key->str);
4686 	if (best_keystring == NULL)
4687 	  return 0;
4688      }
4689 
4690    best_len = strlen (best_keystring);
4691    if (best_len > 4)
4692      return 0;
4693 
4694    /* Db; */
4695    strcpy( retBuf, best_keystring );
4696 
4697    return( best_len );
4698 
4699    /**********
4700    SLsmg_forward (-4);
4701    SLsmg_set_color (color0);
4702    SLsmg_write_nchars (best_keystring, best_len);
4703    Return 0;
4704    *****/
4705 }
4706 
4707 static void
jGktDrawKeyStringAccelKey(Menu_Keystring_Fun_Type * km)4708 jGktDrawKeyStringAccelKey( Menu_Keystring_Fun_Type *km )
4709 {
4710    char keyBuf[5];
4711    char keyBufExt[50] = "                                                  ";
4712    GList *cl;
4713 
4714    /* Dbp2( "Drawing: %x, |%s|\n", *n, ( *n )->name ); */
4715    /* km = ( Menu_Keystring_Fun_Type * ) *n; */
4716    if ( jGtkGetKeystring( km, keyBuf ) )
4717      {
4718 	*keyBufExt = ' ';
4719       /* Dbp1( "AccelKey:    |%s|\n", keyBuf ); */
4720 	if ( !strncmp( keyBuf, "^[", 2 ) )
4721 	  {
4722 	     strcpy( keyBufExt + 5, "ESC " );
4723 	 /* Dbp1( "AccelKeyExt: |%s|\n", keyBufExt ); */
4724 	     strcpy( keyBufExt + 9, keyBuf + 2 );
4725 	 /* Dbp1( "AccelKeyExt: |%s|\n", keyBufExt ); */
4726 	  }
4727 	else
4728 	  {
4729 	     strcpy( keyBufExt + 5, keyBuf );
4730 	  }
4731 
4732      }
4733    else
4734      {
4735 	*keyBuf = '\0';
4736 	*keyBufExt = '\0';
4737      }
4738 
4739    /* Dbp1( "AccelKey:    |%s|\n", keyBuf ); */
4740    /* Dbp1( "AccelKeyExt: |%s|\n", keyBufExt ); */
4741    /* */
4742    cl = gtk_container_get_children(
4743 				   ( GtkContainer * )
4744 				   gtk_container_get_children( ( GtkContainer * ) km->menuItem )->data );
4745    if ( cl && cl->next && GTK_IS_LABEL( ( GtkWidget * ) cl->next->data ) )
4746      {
4747 	gtk_label_set_text( ( GtkLabel * ) cl->next->data, keyBufExt );
4748      }
4749 
4750 }
4751 
4752 static void
jGtkDrawAccelKey(Menu_Popup_Type * p)4753 jGtkDrawAccelKey( Menu_Popup_Type *p )
4754 {
4755    unsigned int i = p->num_subnodes;
4756    Menu_Node_Type **n = p->subnodes;
4757 
4758    for ( i = 0; i < p->num_subnodes; ++i )
4759      {
4760 	if ( ( *n )->type == MENU_NODE_KEYSTRING )
4761 	  {
4762 	     jGktDrawKeyStringAccelKey( ( Menu_Keystring_Fun_Type * ) *n );
4763 	  }
4764 	++n;
4765      }
4766 }
4767 
4768 static gboolean
jGtkPopupMenuActivateCB(GtkMenuItem * w,gpointer data)4769 jGtkPopupMenuActivateCB( GtkMenuItem *w,
4770 			 gpointer     data )
4771 {
4772    Menu_Popup_Type *m = ( Menu_Popup_Type * ) data;
4773    /* Dbp2( "Popup %x: |%s| activated\n", m, m->name ); */
4774    if ( ! ( m->flags & JGTK_MENU_POPUP_PREPARED ) )
4775      {
4776 	jGtkDrawAccelKey( m );
4777       /* Dbp2( "Prepare popup %x: |%s|\n", m, m->name ); */
4778       /* m->flags |= JGTK_MENU_POPUP_PREPARED; */
4779 	jGtkPreparePopup( m, m->select_popup_callback );
4780      }
4781    return( FALSE );
4782 }
4783 
4784 static gboolean
jGtkPrepareCB(GtkMenuItem * w,gpointer data)4785 jGtkPrepareCB( GtkMenuItem *w, gpointer data )
4786 {
4787    Menu_Popup_Type *m = ( Menu_Popup_Type * ) data;
4788    /* Dbp2( "Popup %x: |%s| prepared\n", m, m->name ); */
4789    /* jGtkPreparePopup( m, m->select_popup_callback ); */
4790    return( FALSE );
4791 }
4792 
4793 static void
jGtkResetPopupGtkPrepared(Menu_Popup_Type * m)4794 jGtkResetPopupGtkPrepared( Menu_Popup_Type *m )
4795 {
4796    Menu_Node_Type **l, **lmax;
4797 
4798    m->flags &= ~JGTK_MENU_POPUP_PREPARED;
4799 
4800    l = m->subnodes;
4801    lmax = l + m->num_subnodes;
4802 
4803    while ( l < lmax )
4804      {
4805 	if ( ( *l )->type == 3 ) /* *l->type == 5 should not occur */
4806 	  jGtkResetPopupGtkPrepared( ( Menu_Popup_Type * ) *l );
4807 
4808 	++l;
4809      }
4810 }
4811 
4812 static gboolean
jGtkDeactivateCB(GtkMenuItem * w,gpointer data)4813 jGtkDeactivateCB( GtkMenuItem *w, gpointer data )
4814 {
4815    Menu_Popup_Type *m = ( Menu_Popup_Type * ) data;
4816    /* Dbp2( "Menu shell %x: |%s| deactivated\n", m, m->name ); */
4817    jGtkResetPopupGtkPrepared( m );
4818    /* jGtkPreparePopup( m, m->select_popup_callback ); */
4819    return( FALSE );
4820 }
4821 
4822 static gboolean
jGtkActivateCurrentCB(GtkMenuItem * w,gboolean force,gpointer data)4823 jGtkActivateCurrentCB( GtkMenuItem *w, gboolean force, gpointer data )
4824 {
4825    Menu_Popup_Type *m = ( Menu_Popup_Type * ) data;
4826    /* Dbp2( "Menu shell %x: |%s| activate-current\n", m, m->name ); */
4827    /* jGtkPreparePopup( m, m->select_popup_callback ); */
4828    return( FALSE );
4829 }
4830 
4831 static void
menuCallback(Menu_Node_Type * menu)4832 menuCallback( Menu_Node_Type *menu )
4833 {
4834 
4835    execMenuTbCmd( menu );
4836 
4837    jGtkSetFocus();
4838    Jed_Menus_Active = 0;
4839 
4840    update((Line *) NULL, 0, 0, 1); /* File: screen.c */
4841 
4842    jGtkSetFocus();
4843 }
4844 
4845 # if 0
4846 
4847 int
4848 gtkCreateTBCmd( char *name )
4849 {
4850    char *newKey = SLmalloc( strlen( name ) + 1 );
4851 
4852    if (newKey == NULL)
4853      return -1;
4854 
4855    /* GtkJedMenuType *newMenu = ( GtkJedMenuType * ) SLmalloc( sizeof( GtkJedMenuType ) ); */
4856 
4857    /* printf( "File: %s, Line: %d, gtkCreateMenuBarCmd: |%s|\n", __FILE__, __LINE__, name ); */
4858 
4859    strcpy( newKey, name );
4860    /* printf( "File: %s, Line: %d, gtkCreateMenuBarCmd: |%s|\n", __FILE__, __LINE__, newKey ); */
4861    newMenu->parent = NULL;
4862    newMenu->subMenu = NULL;
4863    newMenu->menuItem = gtk_menu_bar_new();
4864 
4865    g_signal_connect( G_OBJECT( newMenu->menuItem ),
4866 		     "button-release-event",
4867 		     G_CALLBACK( menuBarActivateCurrentCB ),
4868 		     newMenu->menuItem );
4869 /*******
4870    g_signal_connect( G_OBJECT( newMenu->menuItem ),
4871 		     "button-press-event",
4872 		     G_CALLBACK( menuBarActivateCurrentCB ),
4873 		     newMenu->menuItem );
4874 ***********/
4875 
4876    /* printf( "File: %s, Line: %d, Name: %s, menu: %x\n", __FILE__, __LINE__, newKey, newMenu ); */
4877    g_hash_table_insert( menuArray, newKey, newMenu );
4878    return 0;
4879 }
4880 
4881 # endif
4882 
4883 static void
jGtkCreateMenuBarCmd(Menu_Bar_Type * m)4884 jGtkCreateMenuBarCmd( Menu_Bar_Type *m )
4885 {
4886    /* char *newKey = SLmalloc( strlen( name ) + 1 ); */
4887    /* GtkJedMenuType *newMenu = ( GtkJedMenuType * ) SLmalloc( sizeof( GtkJedMenuType ) ); */
4888 
4889    /* printf( "File: %s, Line: %d, gtkCreateMenuBarCmd: |%s|\n", __FILE__, __LINE__, name ); */
4890 
4891    /* strcpy( newKey, name ); */
4892    /* printf( "File: %s, Line: %d, gtkCreateMenuBarCmd: |%s|\n", __FILE__, __LINE__, newKey ); */
4893    /* newMenu->parent = NULL; */
4894    /* newMenu->subMenu = NULL; */
4895    /* newMenu->menuItem = gtk_menu_bar_new(); */
4896 
4897    m->subMenu = gtk_menu_bar_new();
4898 
4899    g_signal_connect( G_OBJECT( m->subMenu ),
4900 		     "button-release-event",
4901 		     G_CALLBACK( menuBarActivateCurrentCB ),
4902 		     NULL );
4903 
4904    g_signal_connect( G_OBJECT( m->subMenu ),
4905 		     "destroy",
4906 		     G_CALLBACK( jGtkDestroyWidget ),
4907 		     &( m->subMenu ) );
4908 
4909    g_signal_connect( G_OBJECT( m->subMenu ),
4910 		     "deactivate",
4911 		     G_CALLBACK( jGtkDeactivateCB ),
4912 		     m );
4913 
4914    g_signal_connect( G_OBJECT( m->subMenu ),
4915 		     "activate-current",
4916 		     G_CALLBACK( jGtkActivateCurrentCB ),
4917 		     m );
4918 }
4919 
4920 void
gtkSetBufferMenuBarCmd(char * name)4921 gtkSetBufferMenuBarCmd( char *name )
4922 {
4923    Menu_Bar_Type *menu = menu_find_menu_bar( name, True );
4924 
4925    /* Db; */
4926    /* Dbp2( ">>>: ----------->Menu: |%s|%x|<<<\n", name, menu ); */
4927 
4928    if ( menu )
4929      jGtkAttachMenubar( menu->subMenu );
4930 
4931 # if 0
4932    if ( menu && menu->menuItem != JGtkWin->appWMenuBar )
4933      {
4934       /* Dbp1( "Menu: %x\n", menu ); */
4935 	gtk_box_pack_start( GTK_BOX( JGtkWin->appWGrid ), menu->menuItem, False, False, 0 );
4936 	gtk_box_reorder_child( GTK_BOX( JGtkWin->appWGrid ), menu->menuItem, 1 );
4937 	if ( JGtkWin->appWMenuBar )
4938 	  gtk_container_remove( GTK_CONTAINER( JGtkWin->appWGrid ), JGtkWin->appWMenuBar );
4939 	JGtkWin->appWMenuBar = menu->menuItem;
4940 	gtk_widget_show_all( menu->menuItem );
4941      }
4942 # endif
4943 
4944 }
4945 
4946 # if 0
4947 
4948 static void
4949 jGtkSimpleAppendTBCmd( char *dest, char *menuName )
4950 {
4951    char *gtkName = createMenuNameMnemonic( menuName );
4952    /* GtkJedMenuType *menu = g_hash_table_lookup( menuArray, dest ); */
4953    /* GtkJedMenuType *newMenu = ( GtkJedMenuType * ) SLmalloc( sizeof( GtkJedMenuType ) ); */
4954 
4955    /* newMenu->parent = menu; */
4956    /* newMenu->menuItem = gtk_menu_item_new_with_mnemonic( gtkName ); */
4957    SLfree( gtkName );
4958    newMenu->subMenu = gtk_menu_new();
4959 
4960    g_signal_connect( G_OBJECT( newMenu->menuItem ),
4961 		     "destroy",
4962 		     G_CALLBACK( jGtkDestroyWidget ),
4963 		     &( newMenu->menuItem ) );
4964 
4965    g_signal_connect( G_OBJECT( newMenu->subMenu ),
4966 		     "destroy",
4967 		     G_CALLBACK( jGtkDestroyWidget ),
4968 		     &( newMenu->subMenu ) );
4969 
4970    gtk_widget_show_all( newMenu->menuItem );
4971    gtk_widget_show_all( newMenu->subMenu );
4972 
4973    gtk_menu_item_set_submenu( GTK_MENU_ITEM( newMenu->menuItem ), newMenu->subMenu );
4974 
4975    /* printf( "gtkSimpleAppendPopupMenuCmd (File: %s, Line: %d): dest: |%s| name: |%s|\n", __FILE__, __LINE__, dest, menuName ); */
4976 
4977    if ( menu->parent )
4978      {
4979 	gtk_menu_shell_append( GTK_MENU_SHELL( menu->subMenu ), newMenu->menuItem );
4980      }
4981    else
4982      {
4983 	gtk_menu_bar_append( GTK_MENU_BAR( menu->menuItem ), newMenu->menuItem );
4984      }
4985 
4986    addNewMenuPath( dest, menuName, newMenu );
4987 }
4988 
4989 # endif
4990 
4991 static void
jGtkSimpleInsertPopupMenuCmd(Menu_Popup_Type * m,int n)4992 jGtkSimpleInsertPopupMenuCmd( Menu_Popup_Type *m, int n )
4993 {
4994    char *gtkName = createMenuNameMnemonic( m->name );
4995 
4996    m->menuItem = gtk_menu_item_new_with_mnemonic( gtkName );
4997    SLfree( gtkName );
4998    m->subMenu = gtk_menu_new();
4999 
5000    gtk_menu_item_set_submenu( GTK_MENU_ITEM( m->menuItem ), m->subMenu );
5001 
5002    g_signal_connect( G_OBJECT( m->menuItem ),
5003 		     "destroy",
5004 		     G_CALLBACK( jGtkDestroyWidget ),
5005 		     &( m->menuItem ) );
5006 
5007    g_signal_connect( G_OBJECT( m->subMenu ),
5008 		     "destroy",
5009 		     G_CALLBACK( jGtkDestroyWidget ),
5010 		     &( m->subMenu ) );
5011 
5012    g_signal_connect( G_OBJECT( m->menuItem ),
5013 		     "activate",
5014 		     G_CALLBACK( jGtkPopupMenuActivateCB ),
5015 		     ( gpointer ) m );
5016 
5017    /* Dbp2( "Name: |%x|%s|\n", m, m->name ); */
5018 
5019    gtk_widget_show_all( m->menuItem );
5020    gtk_widget_show_all( m->subMenu );
5021 
5022    /* printf( "gtkSimpleAppendPopupMenuCmd (File: %s, Line: %d): dest: |%s| name: |%s|\n", __FILE__, __LINE__, dest, menuName ); */
5023 
5024    /* if ( m->parent->parent ) */
5025    /*   { */
5026    gtk_menu_shell_insert( GTK_MENU_SHELL( m->parent->subMenu ), m->menuItem, n );
5027    /*    } */
5028    /* else */
5029    /*   { */
5030    /*    gtk_menu_shell_insert( GTK_MENU_SHELL( m->parent->menuItem ), m->menuItem, n ); */
5031    /*    } */
5032 }
5033 
5034 # if 0
5035 
5036 void
5037 checkAndCreateMenuPath( char *path )
5038 {
5039    /* char *savPath = path; */
5040    char *savPathBeg = path;
5041    char *savPathEnd = path;
5042 
5043    while ( *savPathEnd )
5044      {
5045 	if ( *savPathEnd == '.' )
5046 	  {
5047 	 /* the char-sequence .. has occured */
5048 	     if ( savPathBeg == savPathEnd )
5049 	       {
5050 		  savPathBeg++;
5051 		  savPathEnd++;
5052 	       }
5053 	     else
5054 	       {
5055 		  *savPathEnd = '\0'; /* temporary End of String; */
5056 		  if ( g_hash_table_lookup( menuArray, path ) )
5057 		    {
5058 	       /* Path exists */
5059 		       *savPathEnd = '.';
5060 		       ++savPathEnd;
5061 		       savPathBeg = savPathEnd;
5062 		    }
5063 		  else
5064 		    {
5065 	       /* Path does not exist */
5066 		       if ( savPathBeg == path )
5067 			 {
5068 		  /* First part does not exist ==> new Menu Bar */
5069 			    gtkCreateTBCmd( path );
5070 			    *savPathEnd = '.';
5071 			    ++savPathEnd;
5072 			    savPathBeg = savPathEnd;
5073 			 }
5074 		       else
5075 			 {  /* a new submenu needs to be created */
5076 			    char savChar;
5077 
5078 			    --savPathBeg;
5079 			    savChar = *savPathBeg;
5080 			    *savPathBeg = '\0';
5081 			    savPathBeg++;
5082 			    jGtkSimpleAppendTBCmd( path, savPathBeg );
5083 			    --savPathBeg;
5084 			    *savPathBeg = savChar;
5085 			    *savPathEnd = '.';
5086 			    ++savPathEnd;
5087 			    savPathBeg = savPathEnd;
5088 			 }
5089 		    }
5090 	       }
5091 	  }
5092 	else
5093 	  {
5094 	     ++savPathEnd;
5095 	  }
5096      }
5097 
5098    if ( savPathBeg != savPathEnd )
5099      {
5100 	if ( !g_hash_table_lookup( menuArray, path ) )
5101 	  {
5102 	 /* Path does not exist */
5103 	     if ( savPathBeg == path )
5104 	       {
5105 	    /* First part does not exist ==> new Menu Bar */
5106 		  gtkCreateTBCmd( path );
5107 	       }
5108 	     else
5109 	       {  /* a new submenu needs to be created */
5110 		  char savChar;
5111 
5112 		  --savPathBeg;
5113 		  savChar = *savPathBeg;
5114 		  *savPathBeg = '\0';
5115 		  savPathBeg++;
5116 		  gtkAppendTBCmd( path, savPathBeg );
5117 		  --savPathBeg;
5118 		  *savPathBeg = savChar;
5119 	       }
5120 	  }
5121      }
5122 }
5123 
5124 void
5125 gtkAppendTBCmd( char *dest, char *menu )
5126 {
5127    /* printf( "gtkAppendPopupMenuCmd (File: %s, Line: %d): dest: |%s| menu: |%s|\n", __FILE__, __LINE__, dest, menu ); */
5128    if ( !checkMenuPathExists( dest, menu ) )
5129      {
5130 	checkAndCreateMenuPath( dest );
5131 	jGtkSimpleAppendTBCmd( dest, menu );
5132      }
5133 }
5134 
5135 # endif
5136 
5137 static void
jGtkInsertPopupMenuCmd(Menu_Popup_Type * m,int n)5138 jGtkInsertPopupMenuCmd( Menu_Popup_Type *m, int n )
5139 {
5140    /* printf( "gtkAppendPopupMenuCmd (File: %s, Line: %d): dest: |%s| menu: |%s|\n", __FILE__, __LINE__, dest, menu ); */
5141 
5142    if ( m && !m->menuItem && !m->subMenu && m->parent &&
5143 	( m->parent->type == 5 || m->parent->type == 3 ) )
5144      {
5145 	jGtkSimpleInsertPopupMenuCmd( m, n );
5146      }
5147    /* m->flags &= ~JGTK_MENU_POPUP_PREPARED; */
5148    /* m->flags = 0; */
5149 }
5150 
5151 static void
jGtkInsertSeparatorCmd(Menu_Popup_Type * m,Menu_Node_Type * sep,int n)5152 jGtkInsertSeparatorCmd( Menu_Popup_Type *m, Menu_Node_Type *sep, int n )
5153 {
5154    if ( m && m->subMenu && sep )
5155      {
5156 	sep->menuItem = gtk_separator_menu_item_new();
5157 
5158 	g_signal_connect( G_OBJECT( sep->menuItem ),
5159 			  "destroy",
5160 			  G_CALLBACK( jGtkDestroyWidget ),
5161 			  &( sep->menuItem ) );
5162 
5163 	gtk_menu_shell_insert( GTK_MENU_SHELL( m->subMenu ), sep->menuItem, n + 1 );
5164 
5165 	gtk_widget_show_all( sep->menuItem );
5166      }
5167 }
5168 
5169 static void
jGtkMenuItemNew(Menu_Popup_Type * menu,Menu_Node_Type * newNode,int n)5170 jGtkMenuItemNew( Menu_Popup_Type *menu, Menu_Node_Type *newNode, int n )
5171 {
5172 
5173    if ( menu && menu->subMenu && newNode )
5174      {
5175 	char *gtkName = createMenuNameMnemonic( newNode->name );
5176 
5177 	if ( isMnemonic( newNode->name ) )
5178 	  {
5179 	     newNode->menuItem = gtk_menu_item_new_with_mnemonic( gtkName );
5180 	  }
5181 	else
5182 	  {
5183 	     newNode->menuItem = gtk_menu_item_new_with_label( gtkName );
5184 	  }
5185 
5186 	g_signal_connect( G_OBJECT( newNode->menuItem ),
5187 			  "destroy",
5188 			  G_CALLBACK( jGtkDestroyWidget ),
5189 			  &( newNode->menuItem ) );
5190 
5191 	SLfree( gtkName );
5192 
5193 	gtk_menu_shell_insert( GTK_MENU_SHELL( menu->subMenu ), newNode->menuItem, n );
5194 
5195 	gtk_widget_show_all( newNode->menuItem );
5196 
5197       /********
5198       g_signal_connect_swapped( G_OBJECT( newNode->menuItem ), "activate",
5199 				G_CALLBACK( menuCallback ),
5200 				( gpointer ) newNode );
5201       **********/
5202 	g_signal_connect( G_OBJECT( newNode->menuItem ), "activate",
5203 			  G_CALLBACK( toolbarCallback ),
5204 			  ( gpointer ) newNode );
5205      }
5206 
5207 }
5208 
5209 static void
jGtkMenuKeystringItemNew(Menu_Popup_Type * menu,Menu_Node_Type * newNode,int n)5210 jGtkMenuKeystringItemNew( Menu_Popup_Type *menu, Menu_Node_Type *newNode, int n )
5211 {
5212    GtkWidget *l;
5213    GtkWidget *lb;
5214 
5215    if ( menu && menu->subMenu && newNode )
5216      {
5217 	char *gtkName = createMenuNameMnemonic( newNode->name );
5218 
5219 	newNode->menuItem = gtk_menu_item_new();
5220 
5221 	lb = gtk_hbox_new( 0, 0 );
5222 
5223 	gtk_container_add( ( GtkContainer * ) newNode->menuItem, lb );
5224 
5225 	l = gtk_label_new( " " );
5226 
5227 	gtk_box_pack_start( ( GtkBox * ) lb, l, True, True, 0 );
5228 
5229 	if ( isMnemonic( newNode->name ) )
5230 	  {
5231 	     gtk_label_set_markup_with_mnemonic( ( GtkLabel * ) l, gtkName );
5232 	 /* newNode->menuItem = gtk_menu_item_new_with_mnemonic( gtkName ); */
5233 	  }
5234 	else
5235 	  {
5236 	     gtk_label_set_markup( ( GtkLabel * ) l, gtkName );
5237 	 /* newNode->menuItem = gtk_menu_item_new_with_label( gtkName ); */
5238 	  }
5239 
5240 	gtk_misc_set_alignment( ( GtkMisc * ) l, 0, 0 );
5241       /* gtk_label_set_justify( ( GtkLabel * ) l, GTK_JUSTIFY_LEFT ); */
5242 
5243 	l = gtk_label_new( " " );
5244 
5245 	gtk_box_pack_start( ( GtkBox * ) lb, l, False, False, 0 );
5246 
5247 	g_signal_connect( G_OBJECT( newNode->menuItem ),
5248 			  "destroy",
5249 			  G_CALLBACK( jGtkDestroyWidget ),
5250 			  &( newNode->menuItem ) );
5251 
5252 	SLfree( gtkName );
5253 
5254 	gtk_menu_shell_insert( GTK_MENU_SHELL( menu->subMenu ), newNode->menuItem, n );
5255 
5256 	gtk_widget_show_all( newNode->menuItem );
5257 
5258       /********
5259       g_signal_connect_swapped( G_OBJECT( newNode->menuItem ), "activate",
5260 				G_CALLBACK( menuCallback ),
5261 				( gpointer ) newNode );
5262       **********/
5263 	g_signal_connect( G_OBJECT( newNode->menuItem ), "activate",
5264 			  G_CALLBACK( toolbarCallback ),
5265 			  ( gpointer ) newNode );
5266 
5267 	jGktDrawKeyStringAccelKey( ( Menu_Keystring_Fun_Type * ) newNode );
5268      }
5269 
5270 }
5271 
5272 # if 0
5273 void
5274 gtkMenuDeleteItemCmd( char *menu )
5275 {
5276 }
5277 
5278 void
5279 gtkMenuDeleteItemsCmd( char *menu )
5280 {
5281 }
5282 
5283 # endif
5284 
5285 void
gtkSetObjectAvailableCmd(char * name)5286 gtkSetObjectAvailableCmd( char *name )
5287 {
5288 }
5289 
5290 /********************************************************************
5291  ********************************************************************
5292  *****     Toolbar functions
5293  *******************************************************************
5294  *******************************************************************/
5295 
5296 void
jgtk_initToolbarArray(void)5297 jgtk_initToolbarArray(void)
5298 {
5299    /* menuArray = g_hash_table_new( g_str_hash, g_str_equal ); */
5300 }
5301 
5302 extern int execTBKeyFeedCmd( char * );
5303 
5304 extern int split_window( void );
5305 
5306 void
toolbarCallback(GtkWidget * w,gpointer data)5307 toolbarCallback( GtkWidget *w, gpointer data )
5308 {
5309    Menu_Node_Type *menu = ( Menu_Node_Type * ) data;
5310    /* Dbp1( "Toolbar clicked\n", 1 ); */
5311    /* Dbp1( "Menu Item: %x selected!\n", menu ); */
5312    /* Dbp1( "Path: |%s| selected!\n", menu->name ); */
5313 
5314    if ( actTBCmdNode )
5315      {
5316 	Menu_Keystring_Fun_Type *tmp = ( Menu_Keystring_Fun_Type * ) menu;
5317 
5318       /* Dbp1( "ActTBCmdNode: %x\n", actTBCmdNode ); */
5319 
5320 	if ( tmp && tmp->type == MENU_NODE_TYPEDKEYS )
5321 	  {
5322 	 /* Dbp6( "keyStr[0]: %d, |%c|, keyStr[1]: %d, |%c|, keyStr[2]: %d, |%c|\n", tmp->keystring[0], tmp->keystring[0], tmp->keystring[1], tmp->keystring[1], tmp->keystring[2], tmp->keystring[2] ); */
5323 	     jgtk_createKeyEvents( tmp->keystring );
5324 	  }
5325 	else
5326 	  {
5327 	     jgtk_createKeyEvents( SLang_process_keystring( "^M" ) );
5328 	  }
5329      }
5330    else
5331      {
5332 	actTBCmdNode = ( Menu_Node_Type * ) data;
5333       /* Dbp1( "ActTBCmdNode: %x\n", actTBCmdNode ); */
5334 
5335 	if ( actTBCmdNode )
5336 	  {
5337 	 /* Dbp1( "ActTBCmdNode: %x\n", actTBCmdNode ); */
5338 	     if ( actTBCmdNode->type == MENU_NODE_TYPEDKEYS )
5339 	       {
5340 		  jgtk_createKeyEvents( ( ( Menu_Keystring_Fun_Type * ) actTBCmdNode )->keystring );
5341 		  actTBCmdNode = NULL;
5342 	       }
5343 	     else if ( !IN_MINI_WINDOW )
5344 	       {
5345 	    /* Dbp1( "IN_MINI_WINDOW: %d\n", IN_MINI_WINDOW ); */
5346 		  jgtk_createKeyEvents( SLang_process_keystring( TB_SEL_KEY_SEQ ) );
5347 	       }
5348 	     else
5349 	       {
5350 		  actTBCmdNode = NULL;
5351 	       }
5352 	 /* Dbp1( "Dummy: %d\n", 1 ); */
5353 	  }
5354       /* tbActive = 1; */
5355      }
5356 }
5357 
5358 void
gtkCreateToolbarCmd(Menu_Bar_Type * mb)5359 gtkCreateToolbarCmd( Menu_Bar_Type *mb )
5360 {
5361    /* char *newKey = SLmalloc( strlen( mb->name ) + 1 ); */
5362    GtkToolbar *tb = ( GtkToolbar * ) gtk_toolbar_new();
5363 
5364    mb->subMenu = ( GtkWidget * ) tb;
5365    mb->menuItem = gtk_handle_box_new();
5366 
5367    g_signal_connect( G_OBJECT( mb->subMenu ), "destroy",
5368 		     G_CALLBACK( jGtkDestroyWidget ),
5369 		     ( gpointer ) &( mb->subMenu ) );
5370    g_signal_connect( G_OBJECT( mb->menuItem ), "destroy",
5371 		     G_CALLBACK( jGtkDestroyWidget ),
5372 		     ( gpointer ) &( mb->menuItem ) );
5373 
5374    gtk_toolbar_set_tooltips( tb, TRUE );
5375 
5376    gtk_toolbar_set_style( tb, GTK_TOOLBAR_ICONS );
5377 
5378    /* strcpy( newKey, mb->name ); */
5379 
5380    gtk_container_add( GTK_CONTAINER( mb->menuItem ), ( GtkWidget * ) tb );
5381    gtk_widget_show_all( ( GtkWidget * ) tb );
5382 }
5383 
5384 /************************************
5385 * jGtkInsertBufferToolbarCmd
5386 *
5387 * debug print: "Name: |%s|, where: %x, *where: %d\n", name, where, *where
5388 *
5389 ************************************/
5390 
5391 static void
jGtkInsertBufferToolbarCmd(char * name,int * where)5392 jGtkInsertBufferToolbarCmd( char *name, int *where )  /*{{{*/
5393 {
5394    Menu_Bar_Type *menu = menu_find_menu_bar( name, 1 );
5395 
5396    /* Dbp1( "Menu: %x\n", menu ); */
5397 
5398    jGtkAddToolbar( menu->menuItem, *where );
5399 }
5400 
5401 void
gtkAddBufferToolbarCmd(char * name)5402 gtkAddBufferToolbarCmd( char *name )  /*{{{*/
5403 {
5404    Menu_Bar_Type *menu = menu_find_menu_bar( name, 1 );
5405 
5406    jGtkAddToolbar( menu->menuItem, -1 );
5407 }
5408 /*}}}*/
5409 
5410 #if GTK_HAS_TOOLTIPS
5411 static gboolean
jGtkQueryTooltipCB(GtkWidget * w,gint x,gint y,gboolean kbM,GtkTooltip * tooltip,gpointer ud)5412 jGtkQueryTooltipCB( GtkWidget *w, gint x, gint y,
5413 		    gboolean    kbM,
5414 		    GtkTooltip *tooltip,
5415 		    gpointer    ud )
5416 {
5417 
5418    gtk_tooltip_set_text( tooltip, ( const gchar * ) ud );
5419 
5420    return( TRUE );
5421 }
5422 #endif
5423 
5424 static void
gtkToolbarStockItemNew(Menu_Popup_Type * parent,Menu_Node_Type * nn,char * iconName,int where)5425 gtkToolbarStockItemNew( Menu_Popup_Type *parent, Menu_Node_Type *nn, char *iconName, int where )
5426 {
5427 #if GTK_HAS_TOOLTIPS
5428    char *ttName;
5429 #endif
5430    GtkWidget *stockW = ( GtkWidget * ) gtk_tool_button_new_from_stock( iconName );
5431 
5432    nn->subMenu = NULL;
5433    nn->menuItem = stockW;
5434 #if GTK_HAS_TOOLTIPS
5435    ttName = SLmalloc( strlen( nn->name ) + 1 );
5436    if (ttName != NULL)
5437      {
5438 	g_object_set( G_OBJECT( stockW ), "has-tooltip", TRUE, NULL );
5439 	strcpy( ttName, nn->name );
5440 
5441 	g_signal_connect( G_OBJECT( stockW ),
5442 			  "query-tooltip",
5443 			  G_CALLBACK( jGtkQueryTooltipCB ),
5444 			  ttName );
5445      }
5446 #endif
5447 
5448    g_object_set( G_OBJECT( stockW ), "has-tooltip", TRUE, NULL );
5449 
5450    gtk_toolbar_insert( ( GtkToolbar * ) parent->subMenu, ( GtkToolItem * ) stockW, where );
5451 
5452    gtk_widget_show_all( stockW );
5453 
5454    g_signal_connect( G_OBJECT( stockW ), "clicked",
5455 		     G_CALLBACK( toolbarCallback ),
5456 		     ( gpointer ) nn );
5457    g_signal_connect( G_OBJECT( stockW ), "destroy",
5458 		     G_CALLBACK( jGtkDestroyWidget ),
5459 		     ( gpointer ) &( nn->menuItem ) );
5460 
5461 }
5462 
5463 static void
gtkToolbarItemNew(Menu_Popup_Type * parent,Menu_Node_Type * nn,char * iconName,int where)5464 gtkToolbarItemNew( Menu_Popup_Type *parent, Menu_Node_Type *nn, char *iconName, int where )
5465 {
5466    gint iconW, iconH;
5467    GdkPixbuf *iconImagePixbuf;
5468    GtkWidget *stockW;
5469 
5470    gtk_icon_size_lookup(
5471 			gtk_toolbar_get_icon_size( ( GtkToolbar * ) parent->subMenu ),
5472 			&iconW, &iconH );
5473 
5474    iconImagePixbuf = gdk_pixbuf_new_from_file_at_size( iconName,
5475 						       iconW, iconH,
5476 						       NULL );
5477 
5478    stockW = ( GtkWidget * ) gtk_tool_button_new(
5479 						gtk_image_new_from_pixbuf( iconImagePixbuf ),
5480 						nn->name );
5481 
5482    nn->subMenu = NULL;
5483    nn->menuItem = stockW;
5484 #if GTK_HAS_TOOLTIPS
5485    gtk_tool_item_set_tooltip_text( GTK_TOOL_ITEM( stockW ), nn->name );
5486 #endif
5487    gtk_toolbar_insert( ( GtkToolbar * ) parent->subMenu, ( GtkToolItem * ) stockW, where );
5488 
5489    gtk_widget_show_all( stockW );
5490 
5491    g_signal_connect( G_OBJECT( stockW ), "clicked",
5492 		     G_CALLBACK( toolbarCallback ),
5493 		     ( gpointer ) nn );
5494 
5495    g_signal_connect( G_OBJECT( stockW ), "destroy",
5496 		     G_CALLBACK( jGtkDestroyWidget ),
5497 		     ( gpointer ) &( nn->menuItem ) );
5498 }
5499 
5500 static void
gtkToolbarAppendSeparatorCmd(Menu_Popup_Type * p,Menu_Node_Type * menu)5501 gtkToolbarAppendSeparatorCmd( Menu_Popup_Type *p, Menu_Node_Type *menu )
5502 {
5503    char *name;
5504    Menu_Bar_Type *parent = ( Menu_Bar_Type * ) p;
5505    GtkWidget *sepW = ( GtkWidget * ) gtk_separator_tool_item_new();
5506 
5507    menu->subMenu = NULL;
5508    menu->menuItem = sepW;
5509 
5510    gtk_toolbar_insert( ( GtkToolbar * ) parent->subMenu, ( GtkToolItem * ) sepW, -1 );
5511 
5512    gtk_widget_show_all( sepW );
5513 
5514    g_signal_connect( G_OBJECT( sepW ), "destroy",
5515 		     G_CALLBACK( jGtkDestroyWidget ),
5516 		     ( gpointer ) &( menu->menuItem ) );
5517 }
5518 
5519 static void
gtkToolbarInsertSeparatorCmd(Menu_Popup_Type * p,Menu_Node_Type * menu,int where)5520 gtkToolbarInsertSeparatorCmd( Menu_Popup_Type *p, Menu_Node_Type *menu, int where )
5521 {
5522    char *name;
5523    Menu_Bar_Type *parent = ( Menu_Bar_Type * ) p;
5524    GtkWidget *sepW = ( GtkWidget * ) gtk_separator_tool_item_new();
5525 
5526    menu->subMenu = NULL;
5527    menu->menuItem = sepW;
5528 
5529    gtk_toolbar_insert( ( GtkToolbar * ) parent->subMenu, ( GtkToolItem * ) sepW, where );
5530 
5531    gtk_widget_show_all( sepW );
5532 
5533    g_signal_connect( G_OBJECT( sepW ), "destroy",
5534 		     G_CALLBACK( jGtkDestroyWidget ),
5535 		     ( gpointer ) &( menu->menuItem ) );
5536 }
5537 
5538 # ifdef HAS_MOUSE
5539 /************************************
5540 * select_menu_via_rc
5541 *
5542 * debug print: " Type: %d, r: %d, c: %d\n", type, r, c
5543 *
5544 ************************************/
5545 
select_menu_via_rc(int type,int r,int c)5546 static int select_menu_via_rc (int type, int r, int c)
5547 {
5548    Menu_Popup_Type *p;
5549 
5550    p = Active_Popup;
5551    while (p != (Menu_Popup_Type *)Active_Menu_Bar)
5552      {
5553 	if ((r >= p->row)
5554 	    && (r < p->max_row)
5555 	    && (c >= p->column)
5556 	    && (c < p->max_col))
5557 	  break;
5558 
5559 	p = p->parent;
5560      }
5561 
5562    if ((p == NULL) || (p->type == MENU_NODE_MENUBAR))
5563      {
5564 	unsigned int i;
5565 	int *item_columns;
5566 
5567 	if (Active_Popup == NULL)
5568 	  return -1;
5569 
5570 	if (r != 0)
5571 	  {
5572 	     if (type != JMOUSE_DRAG)
5573 	       return -1;
5574 
5575 	     if (Active_Popup->type != MENU_NODE_MENUBAR)
5576 	       return 0;
5577 	  }
5578 
5579 	unselect_active_node ((Menu_Popup_Type *) Active_Menu_Bar);
5580 
5581 	i = Active_Menu_Bar->num_subnodes;
5582 	item_columns = Active_Menu_Bar->item_columns;
5583 	while (i > 0)
5584 	  {
5585 	     i--;
5586 
5587 	     if ((i != 0) && (item_columns[i] > c))
5588 	       continue;
5589 
5590 	     p = (Menu_Popup_Type *)Active_Menu_Bar->subnodes[i];
5591 	     if (p->type == MENU_NODE_SEPARATOR)
5592 	       continue;
5593 
5594 	     if (p->flags & MENU_ITEM_UNAVAILABLE)
5595 	       continue;
5596 
5597 	     if (-1 == set_node_selection ((Menu_Popup_Type *) Active_Menu_Bar,
5598 					   (Menu_Node_Type *) p))
5599 	       return -1;
5600 
5601 	     if (-1 == find_active_popup ())
5602 	       return -1;
5603 
5604 	     if (p->type == MENU_NODE_POPUP)
5605 	       return select_menu_cmd ();
5606 	  }
5607 	return -1;
5608      }
5609 
5610    if (p == Active_Popup)
5611      {
5612 	r -= (p->row + 1);
5613 	r += p->visible_node_offset;
5614 	if ((r >= (int)p->num_subnodes) || (r < 0))
5615 	  return 0;
5616 
5617 	if (-1 == set_node_selection (p, p->subnodes[r]))
5618 	  return 0;
5619 
5620 	if ((type != JMOUSE_DRAG)
5621 	    || ((p->subnodes[r]->type == MENU_NODE_POPUP)
5622 		&& (c + 1 >= p->max_col)))
5623 	  select_menu_cmd ();
5624 
5625 	return 0;
5626      }
5627 
5628    while (Active_Popup != p)
5629      back_menu_cmd ();
5630 
5631    return 0;
5632 }
5633 
5634 /************************************
5635 * jed_menu_handle_mouse
5636 *
5637 * debug print: "Type: %d, x: %d, y: %d, button %d, shift: %d\n", type, x, y, button, shift
5638 *
5639 ************************************/
5640 
jed_menu_handle_mouse(unsigned int type,int x,int y,int button,int shift)5641 int jed_menu_handle_mouse (unsigned int type,
5642 			   int x, int y, int button, int shift)
5643 {
5644    (void) shift; (void) button;
5645 
5646    if ((type != JMOUSE_UP) && (type != JMOUSE_DRAG))
5647      return -1;
5648 
5649    /* Dbp1( "################################################################\n", 1 ); */
5650    if ((Jed_Menus_Active == 0)
5651        && (-1 == jed_select_menu_bar ()))
5652      return -1;
5653 
5654    if (-1 == select_menu_via_rc (type, y-1, x-1))
5655      {
5656 	if (type != JMOUSE_DRAG)
5657 	  jed_exit_menu_bar ();
5658      }
5659 
5660    return 0;
5661 }
5662 
5663 #  ifndef IBMPC_SYSTEM
5664 /************************************
5665 * xterm_mouse_cmd
5666 *
5667 * debug print: "(void)\n"
5668 *
5669 ************************************/
5670 
xterm_mouse_cmd(void)5671 static int xterm_mouse_cmd (void)
5672 {
5673    int x, y, b;
5674 
5675    b = my_getkey ();
5676    printf( "File: %s, Line: %d, ch: %d\n", __FILE__, __LINE__, b );
5677    x = (unsigned char) my_getkey () - 32;
5678    y = (unsigned char) my_getkey () - 32;
5679 
5680    /* We need to trigger on the button release event */
5681 
5682    b -= 32;
5683    if ((b & 3) != 3)
5684      return -1;
5685 
5686    return jed_menu_handle_mouse (JMOUSE_UP, x, y, 0, 0);
5687 }
5688 
5689 #  endif 				       /* !IBMPC_SYSTEM */
5690 # endif				       /* HAS_MOUSE */
5691 #endif				       /* JED_HAS_MENUS */
5692