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
23 #include <X11/keysym.h>
24 #include <X11/Xutil.h>
25 #include <X11/Xproto.h>
26 #include <X11/Xatom.h>
27 #include <X11/Intrinsic.h>
32 #include <gdk/gdkprivate.h>
33 #include "gtkpixmapmenuitem.h"
35 #include <gdk_imlib.h>
38 #include "libs/fvwmlib.h"
39 #include "libs/Module.h"
40 #include "libs/PictureBase.h"
43 extern int fvwm_fd
[2];
44 extern char *image_path
;
45 extern GHashTable
*widgets
;
46 extern GtkWidget
*current
;
47 extern GtkWidget
*attach_to_toplevel
;
48 extern unsigned long context
;
49 extern int icon_w
, icon_h
;
53 send_item (GtkWidget
*item
, char *s
)
55 SendText (fvwm_fd
, s
, context
);
60 detacher (GtkWidget
*attach
, GtkMenu
*menu
)
66 find_or_create_menu (char *name
)
71 menu
= g_hash_table_lookup (widgets
, name
);
75 menu
= gtk_menu_new ();
76 gtk_menu_attach_to_widget (GTK_MENU (menu
),
77 attach_to_toplevel
, detacher
);
78 gtk_widget_set_name (menu
, name
);
79 name_copy
= gtk_widget_get_name (menu
);
80 gtk_object_ref (GTK_OBJECT (menu
));
81 gtk_object_sink (GTK_OBJECT (menu
));
82 g_hash_table_insert (widgets
, name_copy
, menu
);
83 gtk_object_ref (GTK_OBJECT (menu
));
85 if (GTK_IS_MENU (menu
))
91 fprintf (stderr
, "%s is not a menu\n", name
);
97 /* from gtkcauldron.c */
98 /* result must be g_free'd */
100 convert_label_with_ampersand (const gchar
* _label
,
101 gint
* accelerator_key
,
105 gchar
*label
= g_strdup (_label
);
106 for (p
= label
;; p
++) {
112 memmove (p
, p
+ 1, strlen (p
));
113 if (*p
== '&') /* use && for an actual & */
115 *underbar_pos
= (unsigned long) p
- (unsigned long) label
;
116 *accelerator_key
= *p
;
124 /* from gtkcauldron.c */
126 create_label_pattern (gchar
* label
, gint underbar_pos
)
129 pattern
= g_strdup (label
);
130 memset (pattern
, ' ', strlen (label
));
131 if (underbar_pos
< strlen (pattern
) && underbar_pos
>= 0)
132 pattern
[underbar_pos
] = '_';
137 /* from gnome-app-helper.c */
138 static GtkAccelGroup
*
139 get_menu_accel_group (GtkMenuShell
*menu_shell
)
143 ag
= gtk_object_get_data (GTK_OBJECT (menu_shell
),
144 "gnome_menu_accel_group");
147 ag
= gtk_accel_group_new ();
148 gtk_accel_group_attach (ag
, GTK_OBJECT (menu_shell
));
149 gtk_object_set_data (GTK_OBJECT (menu_shell
),
150 "gnome_menu_accel_group", ag
);
158 menu_item_new_with_pixmap_and_label (char *file
, char *l_label
, char *r_label
)
160 GtkWidget
*item
, *label
, *icon
, *box
;
161 GdkPixmap
*pixmap
= NULL
;
162 GdkBitmap
*mask
= NULL
;
164 gint accel_key
= 0, underbar_pos
= -1;
165 gchar
*pattern
, *converted_label
;
171 path
= PictureFindImageFile (file
? file
: "", image_path
, R_OK
);
175 item
= gtk_menu_item_new ();
180 im
= gdk_imlib_load_image (path
);
183 if (icon_w
== 0 || icon_h
== 0)
193 gdk_imlib_render (im
, w
, h
);
194 pixmap
= gdk_imlib_move_image (im
);
195 mask
= gdk_imlib_move_mask (im
);
198 pixmap
= gdk_pixmap_create_from_xpm (NULL
, &mask
, NULL
, path
);
202 item
= gtk_pixmap_menu_item_new ();
203 icon
= gtk_pixmap_new (pixmap
, mask
);
204 gtk_pixmap_menu_item_set_pixmap (GTK_PIXMAP_MENU_ITEM (item
), icon
);
205 gtk_widget_show (icon
);
209 item
= gtk_menu_item_new ();
215 converted_label
= convert_label_with_ampersand (l_label
, &accel_key
,
217 label
= gtk_label_new (converted_label
);
218 if (underbar_pos
!= -1)
220 GtkAccelGroup
*accel_group
=
221 get_menu_accel_group (GTK_MENU_SHELL (current
));
223 pattern
= create_label_pattern (converted_label
, underbar_pos
);
224 gtk_label_set_pattern (GTK_LABEL (label
), pattern
);
226 gtk_widget_add_accelerator (item
, "activate_item",
227 accel_group
, accel_key
, 0, 0);
229 g_free (converted_label
);
231 gtk_misc_set_alignment (GTK_MISC (label
), 0.0, 0.5);
234 box
= gtk_hbox_new (0, 0);
235 gtk_box_pack_start (GTK_BOX (box
), label
, 0, 1, 0);
236 label
= gtk_label_new (r_label
);
237 gtk_misc_set_alignment (GTK_MISC (label
), 1.0, 0.5);
238 gtk_box_pack_end (GTK_BOX (box
), label
, 0, 1, 0);
239 gtk_container_add (GTK_CONTAINER (item
), box
);
240 gtk_widget_show_all (box
);
244 gtk_container_add (GTK_CONTAINER (item
), label
);
245 gtk_widget_show (label
);
253 open_menu (int argc
, char **argv
)
255 g_return_if_fail (argc
> 0);
257 current
= find_or_create_menu (argv
[0]);
262 menu_title (int argc
, char **argv
)
266 g_return_if_fail (argc
> 0);
268 item
= menu_item_new_with_pixmap_and_label
269 (argc
> 1 ? argv
[1] : NULL
, argv
[0], argc
> 2 ? argv
[2] : NULL
);
270 gtk_menu_append (GTK_MENU (current
), item
);
271 gtk_widget_show (item
);
273 This is a hack stolen from the Gnome panel. There ought
277 (GTK_OBJECT (item
), "select",
278 GTK_SIGNAL_FUNC (gtk_menu_item_deselect
), NULL
);
283 menu_separator (int argc
, char **argv
)
287 item
= gtk_menu_item_new ();
288 gtk_menu_append (GTK_MENU (current
), item
);
289 gtk_widget_show (item
);
290 gtk_widget_set_sensitive (item
, 0);
295 menu_item (int argc
, char **argv
)
299 g_return_if_fail (argc
> 1);
301 item
= menu_item_new_with_pixmap_and_label
302 (argc
> 2 ? argv
[2] : NULL
, argv
[0], argc
> 3 ? argv
[3] : NULL
);
303 gtk_menu_append (GTK_MENU (current
), item
);
304 gtk_widget_show (item
);
306 (GTK_OBJECT (item
), "activate",
307 GTK_SIGNAL_FUNC (send_item
), safestrdup (argv
[1]));
312 menu_tearoff_item (int argc
, char **argv
)
316 item
= gtk_tearoff_menu_item_new ();
318 gtk_menu_append (GTK_MENU (current
), item
);
319 gtk_widget_show (item
);
324 menu_submenu (int argc
, char **argv
)
326 GtkWidget
*item
, *submenu
;
328 item
= menu_item_new_with_pixmap_and_label
329 (argc
> 2 ? argv
[2] : NULL
, argv
[0], NULL
);
330 gtk_menu_append (GTK_MENU (current
), item
);
331 gtk_widget_show (item
);
332 submenu
= find_or_create_menu (argv
[1]);
334 gtk_menu_detach (GTK_MENU (submenu
));
335 gtk_menu_item_set_submenu (GTK_MENU_ITEM (item
), submenu
);