Change to the linux kernel coding style
[wmaker-crm.git] / src / menureader.c
Commit [+]AuthorDateLineData
4905ab19 kojima2000-06-21 22:25:10 +00001/* menureader.c- root menu definition readers
6830b057 dan2004-10-12 21:28:27 +00002 *
4905ab19 kojima2000-06-21 22:25:10 +00003 * Window Maker window manager
6830b057 dan2004-10-12 21:28:27 +00004 *
4153e2fd dan2003-01-16 23:30:45 +00005 * Copyright (c) 2000-2003 Alfredo K. Kojima
6830b057 dan2004-10-12 21:28:27 +00006 *
4905ab19 kojima2000-06-21 22:25:10 +00007 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program 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
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
6830b057 dan2004-10-12 21:28:27 +000019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
4905ab19 kojima2000-06-21 22:25:10 +000020 * USA.
21 */
22
4905ab19 kojima2000-06-21 22:25:10 +000023#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/types.h>
27#include <unistd.h>
28
29#include "WindowMaker.h"
30
31#include "misc.h"
32
33#include "rootmenu.h"
34
4905ab19 kojima2000-06-21 22:25:10 +000035typedef struct PLMenuReaderData {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020036 WRootMenuReader *reader;
4905ab19 kojima2000-06-21 22:25:10 +000037
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020038 WMPropList *pl;
39 int curIndex;
6830b057 dan2004-10-12 21:28:27 +000040
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020041 WMPropList **submenu;
42 int *curSubIndex;
43 int submenuDepth;
6830b057 dan2004-10-12 21:28:27 +000044
4905ab19 kojima2000-06-21 22:25:10 +000045} PLMenuReaderData;
46
4905ab19 kojima2000-06-21 22:25:10 +000047typedef struct TextMenuReaderData {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020048 WRootMenuReader *reader;
4905ab19 kojima2000-06-21 22:25:10 +000049
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020050 FILE *file;
6830b057 dan2004-10-12 21:28:27 +000051
4905ab19 kojima2000-06-21 22:25:10 +000052} TextMenuReaderData;
53
4905ab19 kojima2000-06-21 22:25:10 +000054typedef struct PipeMenuReaderData {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020055 WRootMenuReader *reader;
6830b057 dan2004-10-12 21:28:27 +000056
4905ab19 kojima2000-06-21 22:25:10 +000057} PipeMenuReaderData;
58
4905ab19 kojima2000-06-21 22:25:10 +000059typedef struct DirMenuReaderData {
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +020060 WRootMenuReader *reader;
4905ab19 kojima2000-06-21 22:25:10 +000061
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020062 char **dirList;
63 int dirCount;
4905ab19 kojima2000-06-21 22:25:10 +000064
65} DirMenuReaderData;
66
67/*
6830b057 dan2004-10-12 21:28:27 +000068 typedef struct GNOMEMenuReaderData {
69 } GNOMEMenuReaderData;
70 */
4905ab19 kojima2000-06-21 22:25:10 +000071
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020072static WRootMenuData *pl_openMenu(WMPropList * pl);
73static Bool pl_hasMoreData(WRootMenuData * data);
74static Bool pl_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut);
75static void pl_closeMenuFile(WRootMenuData * data);
4905ab19 kojima2000-06-21 22:25:10 +000076
77static WRootMenuData *text_openMenuFile(char *path);
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020078static Bool text_hasMoreData(WRootMenuData * data);
79static Bool text_nextCommand(WRootMenuData * data,
80 char **title, char **command, char **parameter, char **shortcut);
81static void text_closeMenuFile(WRootMenuData * data);
4905ab19 kojima2000-06-21 22:25:10 +000082
83static WRootMenuData *dir_openMenuFile(char *path);
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020084static Bool dir_hasMoreData(WRootMenuData * data);
85static Bool dir_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut);
86static void dir_closeMenuFile(WRootMenuData * data);
4905ab19 kojima2000-06-21 22:25:10 +000087
88static WRootMenuReader PLMenuReader = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020089 pl_hasMoreData,
90 pl_nextCommand,
91 pl_closeMenuFile
4905ab19 kojima2000-06-21 22:25:10 +000092};
93
94static WRootMenuReader TextMenuReader = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +020095 text_hasMoreData,
96 text_nextCommand,
97 text_closeMenuFile
4905ab19 kojima2000-06-21 22:25:10 +000098};
99
100static WRootMenuReader DirMenuReaderData = {
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200101 dir_hasMoreData,
102 dir_nextCommand,
103 dir_closeMenuFile
4905ab19 kojima2000-06-21 22:25:10 +0000104};
105
106/*
6830b057 dan2004-10-12 21:28:27 +0000107 WRootMenuReader GNOMEMenuReaderData = {
108 };
109 */
4905ab19 kojima2000-06-21 22:25:10 +0000110
4905ab19 kojima2000-06-21 22:25:10 +0000111#define LINESIZE 1024
112
113static char linebuf[LINESIZE];
114
4905ab19 kojima2000-06-21 22:25:10 +0000115/* ---------- proplist ---------- */
116
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200117static WRootMenuData *pl_openMenuFile(WMPropList * pl)
4905ab19 kojima2000-06-21 22:25:10 +0000118{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200119 PLRootMenuData *data = wmalloc(sizeof(PLRootMenuData));
4905ab19 kojima2000-06-21 22:25:10 +0000120
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200121 data->reader = PLMenuReader;
4905ab19 kojima2000-06-21 22:25:10 +0000122
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200123 data->pl = pl;
124 data->curIndex = 0;
4905ab19 kojima2000-06-21 22:25:10 +0000125
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200126 data->submenu = NULL;
127 data->curSubIndex = NULL;
128 data->submenuDepth = 0;
4905ab19 kojima2000-06-21 22:25:10 +0000129
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200130 return data;
4905ab19 kojima2000-06-21 22:25:10 +0000131}
132
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200133static Bool pl_hasMoreData(WRootMenuData * data)
4905ab19 kojima2000-06-21 22:25:10 +0000134{
135}
136
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200137static Bool pl_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut)
4905ab19 kojima2000-06-21 22:25:10 +0000138{
139}
140
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200141static void pl_closeMenuFile(WRootMenuData * data)
4905ab19 kojima2000-06-21 22:25:10 +0000142{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200143 if (data->submenu)
144 wfree(data->submenu);
145 if (data->curSubIndex)
146 wfree(data->curSubIndex);
4905ab19 kojima2000-06-21 22:25:10 +0000147
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200148 WMReleasePropList(data->pl);
6830b057 dan2004-10-12 21:28:27 +0000149
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200150 wfree(data);
4905ab19 kojima2000-06-21 22:25:10 +0000151}
152
4905ab19 kojima2000-06-21 22:25:10 +0000153/* ---------- text ---------- */
154
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200155static WRootMenuData *text_openMenuFile(char *path)
4905ab19 kojima2000-06-21 22:25:10 +0000156{
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200157 TextMenuReaderData *data;
6830b057 dan2004-10-12 21:28:27 +0000158
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200159 data = wmalloc(sizeof(TextMenuReaderData));
160 data->reader = TextMenuReader;
6830b057 dan2004-10-12 21:28:27 +0000161
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200162 data->file = fopen(path, "rb");
163 if (!data->file) {
4905ab19 kojima2000-06-21 22:25:10 +0000164
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200165 return NULL;
166 }
4905ab19 kojima2000-06-21 22:25:10 +0000167}
168
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200169static Bool text_hasMoreData(WRootMenuData * data)
4905ab19 kojima2000-06-21 22:25:10 +0000170{
171}
172
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200173static Bool text_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut)
4905ab19 kojima2000-06-21 22:25:10 +0000174{
175}
176
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200177static void text_closeMenuFile(WRootMenuData * data)
4905ab19 kojima2000-06-21 22:25:10 +0000178{
179}
180
4905ab19 kojima2000-06-21 22:25:10 +0000181/* ---------- directory ---------- */
182
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200183static WRootMenuData *dir_openMenuFile(char *paths, time_t * timestamp)
4905ab19 kojima2000-06-21 22:25:10 +0000184{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200185 DirMenuReaderData *data;
186 char **dirs;
187 int dirN;
188 time_t checksum = 0;
189 int i, c;
190
191 /* timestamp for directory is a "checksum" of the directory times */
192
193 wtokensplit(paths, &dirs, &dirN);
194
195 if (dirN == 0) {
196 return NULL;
197 }
198
199 for (c = 0, i = 0; i < dirN; i++) {
200 char *tmp;
201
202 if (strcmp(dirs[i], "-noext") == 0) {
203 i++;
204 continue;
205 }
206
207 tmp = wexpandpath(dirs[i]);
208 wfree(dirs[i]);
209 dirs[i] = tmp;
210
211 if (stat(dirs[i], &stat_buf) < 0) {
212 wsyserror(_("%s:could not stat menu"), dirs[i]);
213 wfree(dirs[i]);
214 dirs[i] = NULL;
215 } else {
216 c++;
217 checksum += stat_buf.st_mtime;
218 }
219 }
220
221 if (*timestamp == checksum && *timestamp != 0) {
222 return NULL;
223 }
224
225 if (c == 0) {
226 for (i = 0; i < dirN; i++) {
227 if (dirs[i])
228 wfree(dirs[i]);
229 }
230 wfree(dirs);
231
232 return NULL;
233 }
234
235 data = wmalloc(sizeof(DirMenuReaderData));
236 data->reader = DirMenuReader;
6830b057 dan2004-10-12 21:28:27 +0000237
4905ab19 kojima2000-06-21 22:25:10 +0000238}
239
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200240static Bool dir_hasMoreData(WRootMenuData * data)
4905ab19 kojima2000-06-21 22:25:10 +0000241{
242}
243
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200244static Bool dir_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut)
4905ab19 kojima2000-06-21 22:25:10 +0000245{
246}
247
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200248static void dir_closeMenuFile(WRootMenuData * data)
4905ab19 kojima2000-06-21 22:25:10 +0000249{
250}
251
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200252WRootMenuData *OpenMenu(char *path, time_t * menuTime)
4905ab19 kojima2000-06-21 22:25:10 +0000253{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200254 proplist pl;
255 struct stat stat_buf;
256 WRootMenuData *data;
257
258 /* check whether it's a piped menu */
259 if (*path == '|') {
260 /* piped menus have the following semantics for menuTime:
261 * if it's 0, then it wasnt loaded yet
262 * if it's 1, it was already loaded, so do not reload
263 * (would be too slow)
264 * now, menuTime will only be set to 1 if the pipe command is
265 * specified as ||command instead of |command
266 * in other words ||command means force the submenu to always refresh
267 */
268 if (*menuTime == 0) {
269 data = pipe_openMenu(path);
270 }
271 if (path[1] != '|') {
272 *menuTime = 1;
273 }
274 return data;
275 }
276
277 if (stat(path, &stat_buf) < 0) {
278 wsyserror(_("could not stat() menu file '%s'"));
279 return NULL;
280 }
281
282 /* check whether it's a directory */
283 if (S_ISDIR(stat_buf.st_mode)) {
284 return dir_openMenuFile(path, menuTime);
285 }
286
287 if (*menuTime >= stat_buf.st_mtime && *menuTime != 0) {
288 /* no changes in the menu file */
289 return NULL;
290 }
291
292 /* then check whether it's a proplist menu */
293 pl = WMReadPropListFromFile(path);
294 if (pl && WMIsPLArray(pl)) {
295 *menuTime = stat_buf.st_mtime;
296 return pl_openMenu(pl);
297 }
298
299 *menuTime = stat_buf.st_mtime;
300 /* assume its a plain text menu */
301 return text_openMenuFile(path);
4905ab19 kojima2000-06-21 22:25:10 +0000302}
303
688a56e8 Carlos R. Mafra2009-08-20 00:59:40 +0200304WRootMenuData *ReopenRootMenu(time_t * checkTime, char **menuPath, time_t * menuTimestamp)
4905ab19 kojima2000-06-21 22:25:10 +0000305{
688a56e8
CM
Carlos R. Mafra2009-08-20 00:59:40 +0200306 proplist pl;
307 struct stat stat_buf;
308 char *path;
309
310 if (stat(path, &stat_buf) < 0) {
311 wsyserror(_("could not stat() menu file '%s'"));
312 return NULL;
313 }
314
315 if (*menuTime >= stat_buf.st_mtime && *checkTime != 0) {
316 /* no changes in WMRootMenu, see if the contents changed */
317 if (*menuPath != NULL) {
318 return OpenMenu(*menuPath, menuTimestamp);
319 } else {
320 return NULL;
321 }
322 }
323
324 *checkTime = stat_buf.st_mtime;
325
326 pl = WMReadPropListFromFile(path);
327 if (!pl) {
328 wwarning(_("could not load domain %s from user defaults database"), "WMRootMenu");
329 return NULL;
330 }
331
332 if (WMIsPLString(pl)) {
333 char *tmp;
334 char *path;
335 Bool menu_is_default = False;
336
337 tmp = wexpandpath(WMGetFromPLString(pl));
338
339 path = getLocalizedMenuFile(tmp);
340
341 if (!path) {
342 path = wfindfile(DEF_CONFIG_PATHS, tmp);
343 }
344
345 if (!path) {
346 wwarning(_("could not find menu file '%s' referenced in WMRootMenu"), tmp);
347 path = wfindfile(DEF_CONFIG_PATHS, DEF_MENU_FILE);
348 menu_is_default = True;
349 }
350
351 if (!path) {
352 wwarning(_("could not find any usable menu files. Please check '%s'"), tmp);
353 wfree(tmp);
354 return NULL;
355 }
356
357 wfree(tmp);
358
359 if (*menuPath) {
360 if (strcmp(*menuPath, path) != 0) {
361 *menuTimestamp = 0;
362 wfree(*menuPath);
363 *menuPath = path;
364
365 if (menu_is_default) {
366 wwarning(_
367 ("using default menu file \"%s\" as the menu referenced in WMRootMenu could not be found "),
368 path);
369 }
370 } else {
371 /* the menu path didn't change, but the
372 * pointed file might have changed, so we don't return
373 */
374 }
375 } else {
376 *menuPath = path;
377 }
378
379 return OpenMenu(*menuPath, menuTimestamp);
380 } else if (WMIsPLArray(pl)) {
381
382 *menuTimestamp = stat_buf.st_mtime;
383
384 return pl_openMenu(pl);
385 } else {
386 wwarning(_
387 ("invalid content in menu file '%s'.\nIt should either be a property list menu or the path to the file, enclosed in \"."),
388 path);
389 return NULL;
390 }
4905ab19 kojima2000-06-21 22:25:10 +0000391}