1 /* menu.c - menu interface functions
3 * WMlib - WindowMaker application programming interface
5 * Copyright (C) 1997-2003 Alfredo K. Kojima
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
27 #include <X11/Xutil.h>
33 WMMenu
*WMMenuCreate(WMAppContext
* app
, char *title
)
37 if (strlen(title
) > 255)
40 menu
= malloc(sizeof(wmMenu
));
44 menu
->appcontext
= app
;
50 menu
->realized
= False
;
51 menu
->code
= app
->last_menu_tag
++;
53 menu
->entryline
= malloc(strlen(title
) + 32);
54 menu
->entryline2
= malloc(32);
55 if (!menu
->entryline
|| !menu
->entryline2
) {
57 free(menu
->entryline
);
61 sprintf(menu
->entryline
, "%i %i %s", wmBeginMenu
, menu
->code
, title
);
62 sprintf(menu
->entryline2
, "%i %i", wmEndMenu
, menu
->code
);
67 WMMenuAddItem(WMMenu
* menu
, char *text
, WMMenuAction action
,
68 void *clientData
, WMFreeFunction freedata
, char *rtext
)
72 /* max size of right side text */
73 if (rtext
&& strlen(rtext
) > 4)
76 /* max size of menu text */
77 if (strlen(text
) > 255)
80 entry
= malloc(sizeof(wmMenuEntry
));
84 entry
->entryline
= malloc(strlen(text
) + 100);
85 if (!entry
->entryline
) {
91 entry
->order
= menu
->entries
->order
+ 1;
97 entry
->prev
= menu
->entries
;
99 menu
->entries
->next
= entry
;
100 menu
->entries
= entry
;
104 entry
->shortcut
= rtext
;
105 entry
->callback
= action
;
106 entry
->clientData
= clientData
;
107 entry
->free
= freedata
;
108 entry
->tag
= menu
->appcontext
->last_menu_tag
++;
109 entry
->cascade
= NULL
;
110 entry
->enabled
= True
;
113 sprintf(entry
->entryline
, "%i %i %i %i %s", wmNormalItem
, menu
->code
, entry
->tag
, True
, text
);
115 sprintf(entry
->entryline
, "%i %i %i %i %s %s", wmDoubleItem
,
116 menu
->code
, entry
->tag
, True
, rtext
, text
);
120 int WMMenuAddSubmenu(WMMenu
* menu
, char *text
, WMMenu
* submenu
)
124 /* max size of menu text */
125 if (strlen(text
) > 255)
128 entry
= malloc(sizeof(wmMenuEntry
));
132 entry
->entryline
= malloc(strlen(text
) + 100);
133 if (!entry
->entryline
) {
139 entry
->order
= menu
->entries
->order
+ 1;
145 entry
->prev
= menu
->entries
;
147 menu
->entries
->next
= entry
;
148 menu
->entries
= entry
;
151 entry
->shortcut
= NULL
;
152 entry
->callback
= NULL
;
153 entry
->clientData
= NULL
;
154 entry
->tag
= menu
->appcontext
->last_menu_tag
++;
155 entry
->cascade
= submenu
;
156 entry
->enabled
= True
;
158 sprintf(entry
->entryline
, "%i %i %i %i %i %s", wmSubmenuItem
,
159 menu
->code
, entry
->tag
, True
, submenu
->code
, text
);
163 static int countItems(WMMenu
* menu
)
165 wmMenuEntry
*entry
= menu
->first
;
171 if (entry
->cascade
) {
172 c
+= countItems(entry
->cascade
);
180 static void addItems(char **slist
, int *index
, WMMenu
* menu
)
182 wmMenuEntry
*entry
= menu
->first
;
184 slist
[(*index
)++] = menu
->entryline
;
186 slist
[(*index
)++] = entry
->entryline
;
187 if (entry
->cascade
) {
188 addItems(slist
, index
, entry
->cascade
);
192 slist
[(*index
)++] = menu
->entryline2
;
195 static Atom
getatom(Display
* dpy
)
197 static Atom atom
= 0;
200 atom
= XInternAtom(dpy
, WMMENU_PROPNAME
, False
);
205 int WMRealizeMenus(WMAppContext
* app
)
209 XTextProperty text_prop
;
214 /* first count how many menu items there are */
215 count
= countItems(app
->main_menu
);
220 slist
= malloc(count
* sizeof(char *));
225 slist
[0] = "WMMenu 0";
227 addItems(slist
, &i
, app
->main_menu
);
229 if (!XStringListToTextProperty(slist
, i
, &text_prop
)) {
234 XSetTextProperty(app
->dpy
, app
->main_window
, &text_prop
, getatom(app
->dpy
));
236 XFree(text_prop
.value
);