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
);