X-Git-Url: https://repo.or.cz/w/wmaker-crm.git/blobdiff_plain/59fc927dc9f183802621138534fa6eaafe5593ba..688a56e8ab67b56550e2874d9d7423f0d435bfd9:/src/menureader.c diff --git a/src/menureader.c b/src/menureader.c dissimilarity index 80% index 6aa3cf6d..5f35036a 100644 --- a/src/menureader.c +++ b/src/menureader.c @@ -1,463 +1,391 @@ -/* menureader.c- root menu definition readers - * - * Window Maker window manager - * - * Copyright (c) 2000-2003 Alfredo K. Kojima - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. - */ - - -#include -#include -#include -#include -#include - -#include "WindowMaker.h" - -#include "misc.h" - -#include "rootmenu.h" - - -typedef struct PLMenuReaderData { - WRootMenuReader *reader; - - WMPropList *pl; - int curIndex; - - WMPropList **submenu; - int *curSubIndex; - int submenuDepth; - -} PLMenuReaderData; - - -typedef struct TextMenuReaderData { - WRootMenuReader *reader; - - FILE *file; - -} TextMenuReaderData; - - -typedef struct PipeMenuReaderData { - WRootMenuReader *reader; - -} PipeMenuReaderData; - - -typedef struct DirMenuReaderData { - WRootMenuReader *reader; - - char **dirList; - int dirCount; - -} DirMenuReaderData; - -/* - typedef struct GNOMEMenuReaderData { - } GNOMEMenuReaderData; - */ - - - - - -static WRootMenuData *pl_openMenu(WMPropList *pl); -static Bool pl_hasMoreData(WRootMenuData *data); -static Bool pl_nextCommand(WRootMenuData *data, - char **title, - char **command, - char **parameter, - char **shortcut); -static void pl_closeMenuFile(WRootMenuData *data); - - - -static WRootMenuData *text_openMenuFile(char *path); -static Bool text_hasMoreData(WRootMenuData *data); -static Bool text_nextCommand(WRootMenuData *data, - char **title, - char **command, - char **parameter, - char **shortcut); -static void text_closeMenuFile(WRootMenuData *data); - - -static WRootMenuData *dir_openMenuFile(char *path); -static Bool dir_hasMoreData(WRootMenuData *data); -static Bool dir_nextCommand(WRootMenuData *data, - char **title, - char **command, - char **parameter, - char **shortcut); -static void dir_closeMenuFile(WRootMenuData *data); - - - - - - -static WRootMenuReader PLMenuReader = { - pl_hasMoreData, - pl_nextCommand, - pl_closeMenuFile -}; - -static WRootMenuReader TextMenuReader = { - text_hasMoreData, - text_nextCommand, - text_closeMenuFile -}; - -static WRootMenuReader DirMenuReaderData = { - dir_hasMoreData, - dir_nextCommand, - dir_closeMenuFile -}; - -/* - WRootMenuReader GNOMEMenuReaderData = { - }; - */ - - - - -#define LINESIZE 1024 - -static char linebuf[LINESIZE]; - - - -/* ---------- proplist ---------- */ - - -static WRootMenuData* -pl_openMenuFile(WMPropList *pl) -{ - PLRootMenuData *data = wmalloc(sizeof(PLRootMenuData)); - - data->reader = PLMenuReader; - - data->pl = pl; - data->curIndex = 0; - - data->submenu = NULL; - data->curSubIndex = NULL; - data->submenuDepth = 0; - - return data; -} - - -static Bool -pl_hasMoreData(WRootMenuData *data) -{ -} - - -static Bool -pl_nextCommand(WRootMenuData *data, char **title, char **command, - char **parameter, char **shortcut) -{ -} - - -static void -pl_closeMenuFile(WRootMenuData *data) -{ - if (data->submenu) - wfree(data->submenu); - if (data->curSubIndex) - wfree(data->curSubIndex); - - WMReleasePropList(data->pl); - - wfree(data); -} - - -/* ---------- text ---------- */ - - -static WRootMenuData* -text_openMenuFile(char *path) -{ - TextMenuReaderData *data; - - data = wmalloc(sizeof(TextMenuReaderData)); - data->reader = TextMenuReader; - - data->file = fopen(path, "rb"); - if (!data->file) { - - return NULL; - } -} - - -static Bool -text_hasMoreData(WRootMenuData *data) -{ -} - - -static Bool -text_nextCommand(WRootMenuData *data, char **title, char **command, - char **parameter, char **shortcut) -{ -} - - -static void -text_closeMenuFile(WRootMenuData *data) -{ -} - - -/* ---------- directory ---------- */ - - -static WRootMenuData* -dir_openMenuFile(char *paths, time_t *timestamp) -{ - DirMenuReaderData *data; - char **dirs; - int dirN; - time_t checksum = 0; - int i, c; - - /* timestamp for directory is a "checksum" of the directory times */ - - wtokensplit(paths, &dirs, &dirN); - - if (dirN == 0) { - return NULL; - } - - for (c = 0, i = 0; i < dirN; i++) { - char *tmp; - - if (strcmp(dirs[i], "-noext")==0) { - i++; - continue; - } - - tmp = wexpandpath(dirs[i]); - wfree(dirs[i]); - dirs[i] = tmp; - - if (stat(dirs[i], &stat_buf)<0) { - wsyserror(_("%s:could not stat menu"), dirs[i]); - wfree(dirs[i]); - dirs[i] = NULL; - } else { - c++; - checksum += stat_buf.st_mtime; - } - } - - if (*timestamp == checksum && *timestamp != 0) { - return NULL; - } - - if (c == 0) { - for (i = 0; i < dirN; i++) { - if (dirs[i]) - wfree(dirs[i]); - } - wfree(dirs); - - return NULL; - } - - data = wmalloc(sizeof(DirMenuReaderData)); - data->reader = DirMenuReader; - - - -} - - -static Bool -dir_hasMoreData(WRootMenuData *data) -{ -} - -static Bool -dir_nextCommand(WRootMenuData *data, char **title, char **command, - char **parameter, char **shortcut) -{ -} - -static void -dir_closeMenuFile(WRootMenuData *data) -{ -} - - -WRootMenuData* -OpenMenu(char *path, time_t *menuTime) -{ - proplist pl; - struct stat stat_buf; - WRootMenuData *data; - - /* check whether it's a piped menu */ - if (*path == '|') { - /* piped menus have the following semantics for menuTime: - * if it's 0, then it wasnt loaded yet - * if it's 1, it was already loaded, so do not reload - * (would be too slow) - * now, menuTime will only be set to 1 if the pipe command is - * specified as ||command instead of |command - * in other words ||command means force the submenu to always refresh - */ - if (*menuTime == 0) { - data = pipe_openMenu(path); - } - if (path[1] != '|') { - *menuTime = 1; - } - return data; - } - - if (stat(path, &stat_buf) < 0) { - wsyserror(_("could not stat() menu file '%s'")); - return NULL; - } - - /* check whether it's a directory */ - if (S_ISDIR(stat_buf.st_mode)) { - return dir_openMenuFile(path, menuTime); - } - - - if (*menuTime >= stat_buf.st_mtime && *menuTime != 0) { - /* no changes in the menu file */ - return NULL; - } - - /* then check whether it's a proplist menu */ - pl = WMReadPropListFromFile(path); - if (pl && WMIsPLArray(pl)) { - *menuTime = stat_buf.st_mtime; - return pl_openMenu(pl); - } - - *menuTime = stat_buf.st_mtime; - /* assume its a plain text menu */ - return text_openMenuFile(path); -} - - -WRootMenuData* -ReopenRootMenu(time_t *checkTime, char **menuPath, time_t *menuTimestamp) -{ - proplist pl; - struct stat stat_buf; - char *path; - - - if (stat(path, &stat_buf) < 0) { - wsyserror(_("could not stat() menu file '%s'")); - return NULL; - } - - if (*menuTime >= stat_buf.st_mtime && *checkTime != 0) { - /* no changes in WMRootMenu, see if the contents changed */ - if (*menuPath != NULL) { - return OpenMenu(*menuPath, menuTimestamp); - } else { - return NULL; - } - } - - *checkTime = stat_buf.st_mtime; - - pl = WMReadPropListFromFile(path); - if (!pl) { - wwarning(_("could not load domain %s from user defaults database"), - "WMRootMenu"); - return NULL; - } - - if (WMIsPLString(pl)) { - char *tmp; - char *path; - Bool menu_is_default = False; - - tmp = wexpandpath(WMGetFromPLString(pl)); - - path = getLocalizedMenuFile(tmp); - - if (!path) { - path = wfindfile(DEF_CONFIG_PATHS, tmp); - } - - if (!path) { - wwarning(_("could not find menu file '%s' referenced in WMRootMenu"), - tmp); - path = wfindfile(DEF_CONFIG_PATHS, DEF_MENU_FILE); - menu_is_default = True; - } - - if (!path) { - wwarning(_("could not find any usable menu files. Please check '%s'"), - tmp); - wfree(tmp); - return NULL; - } - - wfree(tmp); - - if (*menuPath) { - if (strcmp(*menuPath, path) != 0) { - *menuTimestamp = 0; - wfree(*menuPath); - *menuPath = path; - - if (menu_is_default) { - wwarning(_("using default menu file \"%s\" as the menu referenced in WMRootMenu could not be found "), - path); - } - } else { - /* the menu path didn't change, but the - * pointed file might have changed, so we don't return - */ - } - } else { - *menuPath = path; - } - - return OpenMenu(*menuPath, menuTimestamp); - } else if (WMIsPLArray(pl)) { - - *menuTimestamp = stat_buf.st_mtime; - - return pl_openMenu(pl); - } else { - wwarning(_("invalid content in menu file '%s'.\nIt should either be a property list menu or the path to the file, enclosed in \"."), - path); - return NULL; - } -} - - - +/* menureader.c- root menu definition readers + * + * Window Maker window manager + * + * Copyright (c) 2000-2003 Alfredo K. Kojima + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include +#include + +#include "WindowMaker.h" + +#include "misc.h" + +#include "rootmenu.h" + +typedef struct PLMenuReaderData { + WRootMenuReader *reader; + + WMPropList *pl; + int curIndex; + + WMPropList **submenu; + int *curSubIndex; + int submenuDepth; + +} PLMenuReaderData; + +typedef struct TextMenuReaderData { + WRootMenuReader *reader; + + FILE *file; + +} TextMenuReaderData; + +typedef struct PipeMenuReaderData { + WRootMenuReader *reader; + +} PipeMenuReaderData; + +typedef struct DirMenuReaderData { + WRootMenuReader *reader; + + char **dirList; + int dirCount; + +} DirMenuReaderData; + +/* + typedef struct GNOMEMenuReaderData { + } GNOMEMenuReaderData; + */ + +static WRootMenuData *pl_openMenu(WMPropList * pl); +static Bool pl_hasMoreData(WRootMenuData * data); +static Bool pl_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut); +static void pl_closeMenuFile(WRootMenuData * data); + +static WRootMenuData *text_openMenuFile(char *path); +static Bool text_hasMoreData(WRootMenuData * data); +static Bool text_nextCommand(WRootMenuData * data, + char **title, char **command, char **parameter, char **shortcut); +static void text_closeMenuFile(WRootMenuData * data); + +static WRootMenuData *dir_openMenuFile(char *path); +static Bool dir_hasMoreData(WRootMenuData * data); +static Bool dir_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut); +static void dir_closeMenuFile(WRootMenuData * data); + +static WRootMenuReader PLMenuReader = { + pl_hasMoreData, + pl_nextCommand, + pl_closeMenuFile +}; + +static WRootMenuReader TextMenuReader = { + text_hasMoreData, + text_nextCommand, + text_closeMenuFile +}; + +static WRootMenuReader DirMenuReaderData = { + dir_hasMoreData, + dir_nextCommand, + dir_closeMenuFile +}; + +/* + WRootMenuReader GNOMEMenuReaderData = { + }; + */ + +#define LINESIZE 1024 + +static char linebuf[LINESIZE]; + +/* ---------- proplist ---------- */ + +static WRootMenuData *pl_openMenuFile(WMPropList * pl) +{ + PLRootMenuData *data = wmalloc(sizeof(PLRootMenuData)); + + data->reader = PLMenuReader; + + data->pl = pl; + data->curIndex = 0; + + data->submenu = NULL; + data->curSubIndex = NULL; + data->submenuDepth = 0; + + return data; +} + +static Bool pl_hasMoreData(WRootMenuData * data) +{ +} + +static Bool pl_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut) +{ +} + +static void pl_closeMenuFile(WRootMenuData * data) +{ + if (data->submenu) + wfree(data->submenu); + if (data->curSubIndex) + wfree(data->curSubIndex); + + WMReleasePropList(data->pl); + + wfree(data); +} + +/* ---------- text ---------- */ + +static WRootMenuData *text_openMenuFile(char *path) +{ + TextMenuReaderData *data; + + data = wmalloc(sizeof(TextMenuReaderData)); + data->reader = TextMenuReader; + + data->file = fopen(path, "rb"); + if (!data->file) { + + return NULL; + } +} + +static Bool text_hasMoreData(WRootMenuData * data) +{ +} + +static Bool text_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut) +{ +} + +static void text_closeMenuFile(WRootMenuData * data) +{ +} + +/* ---------- directory ---------- */ + +static WRootMenuData *dir_openMenuFile(char *paths, time_t * timestamp) +{ + DirMenuReaderData *data; + char **dirs; + int dirN; + time_t checksum = 0; + int i, c; + + /* timestamp for directory is a "checksum" of the directory times */ + + wtokensplit(paths, &dirs, &dirN); + + if (dirN == 0) { + return NULL; + } + + for (c = 0, i = 0; i < dirN; i++) { + char *tmp; + + if (strcmp(dirs[i], "-noext") == 0) { + i++; + continue; + } + + tmp = wexpandpath(dirs[i]); + wfree(dirs[i]); + dirs[i] = tmp; + + if (stat(dirs[i], &stat_buf) < 0) { + wsyserror(_("%s:could not stat menu"), dirs[i]); + wfree(dirs[i]); + dirs[i] = NULL; + } else { + c++; + checksum += stat_buf.st_mtime; + } + } + + if (*timestamp == checksum && *timestamp != 0) { + return NULL; + } + + if (c == 0) { + for (i = 0; i < dirN; i++) { + if (dirs[i]) + wfree(dirs[i]); + } + wfree(dirs); + + return NULL; + } + + data = wmalloc(sizeof(DirMenuReaderData)); + data->reader = DirMenuReader; + +} + +static Bool dir_hasMoreData(WRootMenuData * data) +{ +} + +static Bool dir_nextCommand(WRootMenuData * data, char **title, char **command, char **parameter, char **shortcut) +{ +} + +static void dir_closeMenuFile(WRootMenuData * data) +{ +} + +WRootMenuData *OpenMenu(char *path, time_t * menuTime) +{ + proplist pl; + struct stat stat_buf; + WRootMenuData *data; + + /* check whether it's a piped menu */ + if (*path == '|') { + /* piped menus have the following semantics for menuTime: + * if it's 0, then it wasnt loaded yet + * if it's 1, it was already loaded, so do not reload + * (would be too slow) + * now, menuTime will only be set to 1 if the pipe command is + * specified as ||command instead of |command + * in other words ||command means force the submenu to always refresh + */ + if (*menuTime == 0) { + data = pipe_openMenu(path); + } + if (path[1] != '|') { + *menuTime = 1; + } + return data; + } + + if (stat(path, &stat_buf) < 0) { + wsyserror(_("could not stat() menu file '%s'")); + return NULL; + } + + /* check whether it's a directory */ + if (S_ISDIR(stat_buf.st_mode)) { + return dir_openMenuFile(path, menuTime); + } + + if (*menuTime >= stat_buf.st_mtime && *menuTime != 0) { + /* no changes in the menu file */ + return NULL; + } + + /* then check whether it's a proplist menu */ + pl = WMReadPropListFromFile(path); + if (pl && WMIsPLArray(pl)) { + *menuTime = stat_buf.st_mtime; + return pl_openMenu(pl); + } + + *menuTime = stat_buf.st_mtime; + /* assume its a plain text menu */ + return text_openMenuFile(path); +} + +WRootMenuData *ReopenRootMenu(time_t * checkTime, char **menuPath, time_t * menuTimestamp) +{ + proplist pl; + struct stat stat_buf; + char *path; + + if (stat(path, &stat_buf) < 0) { + wsyserror(_("could not stat() menu file '%s'")); + return NULL; + } + + if (*menuTime >= stat_buf.st_mtime && *checkTime != 0) { + /* no changes in WMRootMenu, see if the contents changed */ + if (*menuPath != NULL) { + return OpenMenu(*menuPath, menuTimestamp); + } else { + return NULL; + } + } + + *checkTime = stat_buf.st_mtime; + + pl = WMReadPropListFromFile(path); + if (!pl) { + wwarning(_("could not load domain %s from user defaults database"), "WMRootMenu"); + return NULL; + } + + if (WMIsPLString(pl)) { + char *tmp; + char *path; + Bool menu_is_default = False; + + tmp = wexpandpath(WMGetFromPLString(pl)); + + path = getLocalizedMenuFile(tmp); + + if (!path) { + path = wfindfile(DEF_CONFIG_PATHS, tmp); + } + + if (!path) { + wwarning(_("could not find menu file '%s' referenced in WMRootMenu"), tmp); + path = wfindfile(DEF_CONFIG_PATHS, DEF_MENU_FILE); + menu_is_default = True; + } + + if (!path) { + wwarning(_("could not find any usable menu files. Please check '%s'"), tmp); + wfree(tmp); + return NULL; + } + + wfree(tmp); + + if (*menuPath) { + if (strcmp(*menuPath, path) != 0) { + *menuTimestamp = 0; + wfree(*menuPath); + *menuPath = path; + + if (menu_is_default) { + wwarning(_ + ("using default menu file \"%s\" as the menu referenced in WMRootMenu could not be found "), + path); + } + } else { + /* the menu path didn't change, but the + * pointed file might have changed, so we don't return + */ + } + } else { + *menuPath = path; + } + + return OpenMenu(*menuPath, menuTimestamp); + } else if (WMIsPLArray(pl)) { + + *menuTimestamp = stat_buf.st_mtime; + + return pl_openMenu(pl); + } else { + wwarning(_ + ("invalid content in menu file '%s'.\nIt should either be a property list menu or the path to the file, enclosed in \"."), + path); + return NULL; + } +}