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., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #include <X11/Xutil.h>
32 WMMenu *WMMenuCreate(WMAppContext * app, char *title)
36 if (strlen(title) > 255)
39 menu = malloc(sizeof(wmMenu));
43 menu->appcontext = app;
49 menu->realized = False;
50 menu->code = app->last_menu_tag++;
52 menu->entryline = malloc(strlen(title) + 32);
53 menu->entryline2 = malloc(32);
54 if (!menu->entryline || !menu->entryline2) {
56 free(menu->entryline);
60 sprintf(menu->entryline, "%i %i %s", wmBeginMenu, menu->code, title);
61 sprintf(menu->entryline2, "%i %i", wmEndMenu, menu->code);
66 WMMenuAddItem(WMMenu * menu, char *text, WMMenuAction action,
67 void *clientData, WMFreeFunction freedata, char *rtext)
71 /* max size of right side text */
72 if (rtext && strlen(rtext) > 4)
75 /* max size of menu text */
76 if (strlen(text) > 255)
79 entry = malloc(sizeof(wmMenuEntry));
83 entry->entryline = malloc(strlen(text) + 100);
84 if (!entry->entryline) {
90 entry->order = menu->entries->order + 1;
96 entry->prev = menu->entries;
98 menu->entries->next = entry;
99 menu->entries = entry;
103 entry->shortcut = rtext;
104 entry->callback = action;
105 entry->clientData = clientData;
106 entry->free = freedata;
107 entry->tag = menu->appcontext->last_menu_tag++;
108 entry->cascade = NULL;
109 entry->enabled = True;
112 sprintf(entry->entryline, "%i %i %i %i %s", wmNormalItem, menu->code, entry->tag, True, text);
114 sprintf(entry->entryline, "%i %i %i %i %s %s", wmDoubleItem,
115 menu->code, entry->tag, True, rtext, text);
119 int WMMenuAddSubmenu(WMMenu * menu, char *text, WMMenu * submenu)
123 /* max size of menu text */
124 if (strlen(text) > 255)
127 entry = malloc(sizeof(wmMenuEntry));
131 entry->entryline = malloc(strlen(text) + 100);
132 if (!entry->entryline) {
138 entry->order = menu->entries->order + 1;
144 entry->prev = menu->entries;
146 menu->entries->next = entry;
147 menu->entries = entry;
150 entry->shortcut = NULL;
151 entry->callback = NULL;
152 entry->clientData = NULL;
153 entry->tag = menu->appcontext->last_menu_tag++;
154 entry->cascade = submenu;
155 entry->enabled = True;
157 sprintf(entry->entryline, "%i %i %i %i %i %s", wmSubmenuItem,
158 menu->code, entry->tag, True, submenu->code, text);
162 static int countItems(WMMenu * menu)
164 wmMenuEntry *entry = menu->first;
170 if (entry->cascade) {
171 c += countItems(entry->cascade);
179 static void addItems(char **slist, int *index, WMMenu * menu)
181 wmMenuEntry *entry = menu->first;
183 slist[(*index)++] = menu->entryline;
185 slist[(*index)++] = entry->entryline;
186 if (entry->cascade) {
187 addItems(slist, index, entry->cascade);
191 slist[(*index)++] = menu->entryline2;
194 static Atom getatom(Display * dpy)
196 static Atom atom = 0;
199 atom = XInternAtom(dpy, WMMENU_PROPNAME, False);
204 int WMRealizeMenus(WMAppContext * app)
208 XTextProperty text_prop;
213 /* first count how many menu items there are */
214 count = countItems(app->main_menu);
219 slist = malloc(count * sizeof(char *));
224 slist[0] = "WMMenu 0";
226 addItems(slist, &i, app->main_menu);
228 if (!XStringListToTextProperty(slist, i, &text_prop)) {
233 XSetTextProperty(app->dpy, app->main_window, &text_prop, getatom(app->dpy));
235 XFree(text_prop.value);