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