Update Serbian translation from master branch
[wmaker-crm.git] / wmlib / menu.c
blob6646cd70717fbcd566455e0bc95c3d8ec92fc290
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,
20 * MA 02110-1301, USA.
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <X11/Xlib.h>
27 #include <X11/Xutil.h>
29 #include "WMaker.h"
30 #include "app.h"
31 #include "menu.h"
33 WMMenu *WMMenuCreate(WMAppContext * app, char *title)
35 wmMenu *menu;
37 if (strlen(title) > 255)
38 return NULL;
40 menu = malloc(sizeof(wmMenu));
41 if (!menu)
42 return NULL;
44 menu->appcontext = app;
45 menu->parent = NULL;
46 menu->title = title;
47 menu->entries = NULL;
48 menu->first = NULL;
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) {
56 if (menu->entryline)
57 free(menu->entryline);
58 free(menu);
59 return NULL;
61 sprintf(menu->entryline, "%i %i %s", wmBeginMenu, menu->code, title);
62 sprintf(menu->entryline2, "%i %i", wmEndMenu, menu->code);
63 return menu;
66 int
67 WMMenuAddItem(WMMenu * menu, char *text, WMMenuAction action,
68 void *clientData, WMFreeFunction freedata, char *rtext)
70 wmMenuEntry *entry;
72 /* max size of right side text */
73 if (rtext && strlen(rtext) > 4)
74 return -1;
76 /* max size of menu text */
77 if (strlen(text) > 255)
78 return -1;
80 entry = malloc(sizeof(wmMenuEntry));
81 if (!entry)
82 return -1;
84 entry->entryline = malloc(strlen(text) + 100);
85 if (!entry->entryline) {
86 free(entry);
87 return -1;
90 if (menu->entries)
91 entry->order = menu->entries->order + 1;
92 else {
93 entry->order = 0;
94 menu->first = entry;
96 entry->next = NULL;
97 entry->prev = menu->entries;
98 if (menu->entries)
99 menu->entries->next = entry;
100 menu->entries = entry;
102 entry->menu = menu;
103 entry->text = text;
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;
112 if (!rtext)
113 sprintf(entry->entryline, "%i %i %i %i %s", wmNormalItem, menu->code, entry->tag, True, text);
114 else
115 sprintf(entry->entryline, "%i %i %i %i %s %s", wmDoubleItem,
116 menu->code, entry->tag, True, rtext, text);
117 return entry->tag;
120 int WMMenuAddSubmenu(WMMenu * menu, char *text, WMMenu * submenu)
122 wmMenuEntry *entry;
124 /* max size of menu text */
125 if (strlen(text) > 255)
126 return -1;
128 entry = malloc(sizeof(wmMenuEntry));
129 if (!entry)
130 return -1;
132 entry->entryline = malloc(strlen(text) + 100);
133 if (!entry->entryline) {
134 free(entry);
135 return -1;
138 if (menu->entries)
139 entry->order = menu->entries->order + 1;
140 else {
141 entry->order = 0;
142 menu->first = entry;
144 entry->next = NULL;
145 entry->prev = menu->entries;
146 if (menu->entries)
147 menu->entries->next = entry;
148 menu->entries = entry;
149 entry->menu = menu;
150 entry->text = text;
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);
160 return entry->tag;
163 static int countItems(WMMenu * menu)
165 wmMenuEntry *entry = menu->first;
166 int c;
168 c = 1;
169 while (entry) {
170 c++;
171 if (entry->cascade) {
172 c += countItems(entry->cascade);
174 entry = entry->next;
176 c++;
177 return c;
180 static void addItems(char **slist, int *index, WMMenu * menu)
182 wmMenuEntry *entry = menu->first;
184 slist[(*index)++] = menu->entryline;
185 while (entry) {
186 slist[(*index)++] = entry->entryline;
187 if (entry->cascade) {
188 addItems(slist, index, entry->cascade);
190 entry = entry->next;
192 slist[(*index)++] = menu->entryline2;
195 static Atom getatom(Display * dpy)
197 static Atom atom = 0;
199 if (atom == 0) {
200 atom = XInternAtom(dpy, WMMENU_PROPNAME, False);
202 return atom;
205 int WMRealizeMenus(WMAppContext * app)
207 int i, count;
208 char **slist;
209 XTextProperty text_prop;
211 if (!app->main_menu)
212 return False;
214 /* first count how many menu items there are */
215 count = countItems(app->main_menu);
216 if (count == 0)
217 return True;
219 count++;
220 slist = malloc(count * sizeof(char *));
221 if (!slist) {
222 return False;
225 slist[0] = "WMMenu 0";
226 i = 1;
227 addItems(slist, &i, app->main_menu);
229 if (!XStringListToTextProperty(slist, i, &text_prop)) {
230 free(slist);
231 return False;
233 free(slist);
234 XSetTextProperty(app->dpy, app->main_window, &text_prop, getatom(app->dpy));
236 XFree(text_prop.value);
238 return True;