2 /* This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * This module is all original code
20 * Copyright 1993, Robert Nation
21 * You may use this code for any purpose, as long as the original
22 * copyright remains in the source code and all documentation
25 /* IMPORTANT NOTE: Do *not* use any constant numbers in this file. All values
26 * have to be #defined in the section below or defaults.h to ensure full
27 * control over the menus. */
29 /* ---------------------------- included header files ---------------------- */
35 #include "libs/Parse.h"
36 #include "libs/Strings.h"
38 #include "functions.h"
41 #include "move_resize.h"
46 #include "menustyle.h"
47 #include "menuparameters.h"
49 /* ---------------------------- local definitions -------------------------- */
51 /* ---------------------------- local macros ------------------------------- */
53 /* ---------------------------- imports ------------------------------------ */
55 /* ---------------------------- included code files ------------------------ */
57 /* ---------------------------- local types -------------------------------- */
59 /* ---------------------------- forward declarations ----------------------- */
61 /* ---------------------------- local variables ---------------------------- */
63 /* ---------------------------- exported variables (globals) --------------- */
65 /* ---------------------------- local functions ---------------------------- */
67 static void menu_func(F_CMD_ARGS
, Bool fStaysUp
)
69 struct MenuRoot
*menu
;
70 char *ret_action
= NULL
;
71 struct MenuOptions mops
;
72 char *menu_name
= NULL
;
73 struct MenuParameters mp
;
74 struct MenuReturn mret
;
75 FvwmWindow
* const fw
= exc
->w
.fw
;
76 const Window w
= exc
->w
.w
;
77 const exec_context_t
*exc2
;
79 memset(&mops
, 0, sizeof(mops
));
80 memset(&mret
, 0, sizeof(MenuReturn
));
81 action
= GetNextToken(action
,&menu_name
);
82 action
= get_menu_options(
83 action
, w
, fw
, NULL
, NULL
, NULL
, &mops
);
84 while (action
&& *action
&& isspace((unsigned char)*action
))
88 if (action
&& *action
== 0)
92 menu
= menus_find_menu(menu_name
);
97 fvwm_msg(ERR
,"menu_func","No such menu %s",menu_name
);
104 menu_name
, (fStaysUp
) ? REPEAT_MENU
: REPEAT_POPUP
,NULL
))
109 memset(&mp
, 0, sizeof(mp
));
111 exc2
= exc_clone_context(exc
, NULL
, 0);
113 MR_IS_TEAR_OFF_MENU(menu
) = 0;
114 mp
.flags
.has_default_action
= (action
!= NULL
);
115 mp
.flags
.is_sticky
= fStaysUp
;
116 mp
.flags
.is_submenu
= False
;
117 mp
.flags
.is_already_mapped
= False
;
118 mp
.flags
.is_triggered_by_keypress
=
119 (exc
->x
.etrigger
->type
== KeyPress
);
121 mp
.ret_paction
= &ret_action
;
123 if (mret
.rc
== MENU_DOUBLE_CLICKED
&& action
)
125 execute_function(cond_rc
, exc2
, action
, 0);
127 if (ret_action
!= NULL
)
131 exc_destroy_context(exc2
);
136 /* ---------------------------- interface functions ------------------------ */
138 /* ---------------------------- builtin commands --------------------------- */
140 /* the function for the "Popup" command */
141 void CMD_Popup(F_CMD_ARGS
)
143 menu_func(F_PASS_ARGS
, False
);
148 /* the function for the "Menu" command */
149 void CMD_Menu(F_CMD_ARGS
)
151 menu_func(F_PASS_ARGS
, True
);
156 void CMD_AddToMenu(F_CMD_ARGS
)
160 char *token
, *rest
,*item
;
162 token
= PeekToken(action
, &rest
);
167 mr
= menus_find_menu(token
);
168 if (mr
&& MR_MAPPED_COPIES(mr
) != 0)
170 fvwm_msg(ERR
,"add_item_to_menu", "menu %s is in use", token
);
173 mr
= FollowMenuContinuations(menus_find_menu(token
), &mrPrior
);
176 mr
= NewMenuRoot(token
);
179 /* Set + state to last menu */
180 set_last_added_item(ADDED_MENU
, mr
);
182 rest
= GetNextToken(rest
, &item
);
183 AddToMenu(mr
, item
, rest
, True
/* pixmap scan */, True
, False
);
192 void CMD_DestroyMenu(F_CMD_ARGS
)
195 MenuRoot
*mrContinuation
;
196 Bool do_recreate
= False
;
199 token
= PeekToken(action
, &action
);
204 if (StrEquals(token
, "recreate"))
207 token
= PeekToken(action
, NULL
);
209 mr
= menus_find_menu(token
);
210 if (Scr
.last_added_item
.type
== ADDED_MENU
)
212 set_last_added_item(ADDED_NONE
, NULL
);
216 /* save continuation before destroy */
217 mrContinuation
= MR_CONTINUATION_MENU(mr
);
218 if (!DestroyMenu(mr
, do_recreate
, True
))
222 /* Don't recreate the continuations */
230 void CMD_DestroyMenuStyle(F_CMD_ARGS
)
232 MenuStyle
*ms
= NULL
;
235 name
= PeekToken(action
, NULL
);
238 fvwm_msg(ERR
,"DestroyMenuStyle", "needs one parameter");
242 ms
= menustyle_find(name
);
247 else if (ms
== menustyle_get_default_style())
249 fvwm_msg(ERR
,"DestroyMenuStyle",
250 "cannot destroy default menu style. "
251 "To reset the default menu style use\n %s",
255 else if (ST_USAGE_COUNT(ms
) != 0)
257 fvwm_msg(ERR
, "DestroyMenuStyle", "menu style %s is in use",
265 menus_remove_style_from_menus(ms
);
270 void CMD_ChangeMenuStyle(F_CMD_ARGS
)
273 char *menuname
= NULL
;
274 MenuStyle
*ms
= NULL
;
277 name
= PeekToken(action
, &action
);
280 fvwm_msg(ERR
,"ChangeMenuStyle",
281 "needs at least two parameters");
285 ms
= menustyle_find(name
);
288 fvwm_msg(ERR
,"ChangeMenuStyle", "cannot find style %s", name
);
292 menuname
= PeekToken(action
, &action
);
293 while (menuname
&& *menuname
)
295 mr
= menus_find_menu(menuname
);
298 fvwm_msg(ERR
, "ChangeMenuStyle", "cannot find menu %s",
302 if (MR_MAPPED_COPIES(mr
) != 0)
304 fvwm_msg(ERR
, "ChangeMenuStyle", "menu %s is in use",
310 MR_IS_UPDATED(mr
) = 1;
312 menuname
= PeekToken(action
, &action
);