static WMPropList *processSubmenu(WEditMenu * menu) { WEditMenuItem *item; WMPropList *pmenu; WMPropList *pl; char *s; int i; s = WGetEditMenuTitle(menu); pl = WMCreatePLString(s); pmenu = WMCreatePLArray(pl, NULL); i = 0; while ((item = WGetEditMenuItem(menu, i++))) { WEditMenu *submenu; s = WGetEditMenuItemTitle(item); submenu = WGetEditMenuSubmenu(item); if (submenu) { pl = processSubmenu(submenu); } else { pl = processData(s, WGetEditMenuItemData(item)); } if (!pl) continue; WMAddToPLArray(pmenu, pl); } return pmenu; }
void wWorkspaceSaveState(WMPropList * old_state) { WMPropList *parr, *pstr, *wks_state, *old_wks_state, *foo, *bar; int i; make_keys(); old_wks_state = WMGetFromPLDictionary(old_state, dWorkspaces); parr = WMCreatePLArray(NULL); for (i = 0; i < w_global.workspace.count; i++) { pstr = WMCreatePLString(w_global.workspace.array[i]->name); wks_state = WMCreatePLDictionary(dName, pstr, NULL); WMReleasePropList(pstr); if (!wPreferences.flags.noclip) { pstr = wClipSaveWorkspaceState(i); WMPutInPLDictionary(wks_state, dClip, pstr); WMReleasePropList(pstr); } else if (old_wks_state != NULL) { if ((foo = WMGetFromPLArray(old_wks_state, i)) != NULL) { if ((bar = WMGetFromPLDictionary(foo, dClip)) != NULL) { WMPutInPLDictionary(wks_state, dClip, bar); } } } WMAddToPLArray(parr, wks_state); WMReleasePropList(wks_state); } WMPutInPLDictionary(w_global.session_state, dWorkspaces, parr); WMReleasePropList(parr); }
static void storeData(_Panel *panel) { WMPropList *list; WMPropList *tmp; int i; char *p; list = WMCreatePLArray(NULL, NULL); for (i=0; i<WMGetListNumberOfRows(panel->icoL); i++) { p = WMGetListItem(panel->icoL, i)->text; tmp = WMCreatePLString(p); WMAddToPLArray(list, tmp); } SetObjectForKey(list, "IconPath"); list = WMCreatePLArray(NULL, NULL); for (i=0; i<WMGetListNumberOfRows(panel->pixL); i++) { p = WMGetListItem(panel->pixL, i)->text; tmp = WMCreatePLString(p); WMAddToPLArray(list, tmp); } SetObjectForKey(list, "PixmapPath"); }
static WMPropList *processData(const char *title, ItemData * data) { WMPropList *item; char *s1; static WMPropList *pscut = NULL; static WMPropList *pomenu = NULL; static WMPropList *poplmenu = NULL; int i; if (data == NULL) return NULL; if (!pscut) { pscut = WMCreatePLString("SHORTCUT"); pomenu = WMCreatePLString("OPEN_MENU"); poplmenu = WMCreatePLString("OPEN_PLMENU"); } item = WMCreatePLArray(WMCreatePLString(title), NULL); switch (data->type) { case ExecInfo: if (data->param.exec.command == NULL) goto return_null; #if 1 if (strpbrk(data->param.exec.command, "&$*|><?`=;")) { s1 = "SHEXEC"; } else { s1 = "EXEC"; } #else s1 = "SHEXEC"; #endif if (notblank(data->param.exec.shortcut)) { WMAddToPLArray(item, pscut); WMAddToPLArray(item, WMCreatePLString(data->param.exec.shortcut)); } WMAddToPLArray(item, WMCreatePLString(s1)); WMAddToPLArray(item, WMCreatePLString(data->param.exec.command)); break; case CommandInfo: if (notblank(data->param.command.shortcut)) { WMAddToPLArray(item, pscut); WMAddToPLArray(item, WMCreatePLString(data->param.command.shortcut)); } i = data->param.command.command; WMAddToPLArray(item, WMCreatePLString(commandNames[i])); switch (i) { case 3: case 4: if (data->param.command.parameter) { WMAddToPLArray(item, WMCreatePLString(data->param.command.parameter)); } break; case 6: /* restart */ if (data->param.command.parameter) { WMAddToPLArray(item, WMCreatePLString(data->param.command.parameter)); } break; } break; case PipeInfo: case PLPipeInfo: if (!data->param.pipe.command) goto return_null; if (data->type == PLPipeInfo) WMAddToPLArray(item, poplmenu); else WMAddToPLArray(item, pomenu); if (data->param.pipe.cached) s1 = wstrconcat("| ", data->param.pipe.command); else s1 = wstrconcat("|| ", data->param.pipe.command); WMAddToPLArray(item, WMCreatePLString(s1)); wfree(s1); break; case ExternalInfo: if (!data->param.external.path) goto return_null; WMAddToPLArray(item, pomenu); WMAddToPLArray(item, WMCreatePLString(data->param.external.path)); break; case DirectoryInfo: { int l; char *tmp; if (!data->param.directory.directory || !data->param.directory.command) goto return_null; l = strlen(data->param.directory.directory); l += strlen(data->param.directory.command); l += 32; WMAddToPLArray(item, pomenu); tmp = wmalloc(l); sprintf(tmp, "%s%s WITH %s", data->param.directory.stripExt ? "-noext " : "", data->param.directory.directory, data->param.directory.command); WMAddToPLArray(item, WMCreatePLString(tmp)); wfree(tmp); } break; case WSMenuInfo: WMAddToPLArray(item, WMCreatePLString("WORKSPACE_MENU")); break; case WWindowListInfo: WMAddToPLArray(item, WMCreatePLString("WINDOWS_MENU")); break; default: assert(0); break; } return item; return_null: WMReleasePropList(item); return NULL; }
int main(int argc, char **argv) { struct stat st; int i; int *previousDepth; prog_name = argv[0]; plMenuNodes = WMCreateArray(8); /* grows on demand */ menu = (WMTreeNode *)NULL; parse = NULL; validateFilename = NULL; /* assemblePLMenuFunc passes this around */ previousDepth = (int *)wmalloc(sizeof(int)); *previousDepth = -1; /* currently this is used only by the xdg parser, but it might be useful * in the future localizing other menus, so it won't hurt to have it here. */ parse_locale(NULL, &env_lang, &env_ctry, &env_enc, &env_mod); terminal = find_terminal_emulator(); for (i = 1; i < argc; i++) { if (strncmp(argv[i], "-parser", 7) == 0 && (argv[i][7] == '=' || argv[i][7] == ':' || /* for legacy compatibility */ argv[i][7] == '\0')) { const char *name; if (argv[i][7] == '\0') { if (++i > argc) { fprintf(stderr, "%s: Missing parser name after \"-parser\"\n", prog_name); return 2; } name = argv[i]; } else { name = argv[i] + 8; } if (strcmp(name, "xdg") == 0) { parse = &parse_xdg; } else if (strcmp(name, "wmconfig") == 0) { parse = &parse_wmconfig; validateFilename = &wmconfig_validate_file; } else { fprintf(stderr, "%s: Unknown parser \"%s\"\n", prog_name, name); return 2; } continue; } if (strcmp(argv[i], "--version") == 0) { printf("%s (Window Maker %s)\n", prog_name, VERSION); return 0; } if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "--help") == 0) { print_help(); return 0; } if (parse == NULL) { fprintf(stderr, "%s: argument \"%s\" with no valid parser\n", prog_name, argv[i]); return 2; } #if DEBUG fprintf(stderr, "%s: Using parser \"%s\" to process \"%s\"\n", prog_name, get_parser_name(), argv[i]); #endif if (stat(argv[i], &st) == -1) { fprintf(stderr, "%s: unable to stat \"%s\", %s\n", prog_name, argv[i], strerror(errno)); return 1; } else if (S_ISREG(st.st_mode)) { parse(argv[i], addWMMenuEntryCallback); } else if (S_ISDIR(st.st_mode)) { nftw(argv[i], dirParseFunc, 16, FTW_PHYS); } else { fprintf(stderr, "%s: \"%s\" is not a file or directory\n", prog_name, argv[i]); return 1; } } if (!menu) { fprintf(stderr, "%s: parsers failed to create a valid menu\n", prog_name); return 1; } WMSortTree(menu, menuSortFunc); WMTreeWalk(menu, assemblePLMenuFunc, previousDepth, True); i = WMGetArrayItemCount(plMenuNodes); if (i > 2) { /* more than one submenu unprocessed is almost certainly an error */ fprintf(stderr, "%s: unprocessed levels on the stack. fishy.\n", prog_name); return 3; } else if (i > 1 ) { /* possibly the top-level attachment is not yet done */ WMPropList *first, *next; next = WMPopFromArray(plMenuNodes); first = WMPopFromArray(plMenuNodes); WMAddToPLArray(first, next); WMAddToArray(plMenuNodes, first); } puts(WMGetPropListDescription((WMPropList *)WMGetFromArray(plMenuNodes, 0), True)); return 0; }
/* creates the proplist menu out of the abstract menu representation in `menu'. */ static void assemblePLMenuFunc(WMTreeNode *aNode, void *data) { WMMenuEntry *wm; WMPropList *pl; int pDepth, cDepth; wm = (WMMenuEntry *)WMGetDataForTreeNode(aNode); cDepth = WMGetTreeNodeDepth(aNode); pDepth = *(int *)data; if (pDepth > cDepth) { /* just ascended out of a/several submenu(s) */ WMPropList *last, *but; /* merge the tail up to the current position */ int i; for (i = pDepth - cDepth; i > 0; i--) { last = WMPopFromArray(plMenuNodes); but = WMPopFromArray(plMenuNodes); WMAddToPLArray(but, last); WMAddToArray(plMenuNodes, but); } } if (!wm->CmdLine) { /* new submenu */ WMAddToArray(plMenuNodes, WMCreatePLArray(WMCreatePLString(wm->Name), NULL)); } else { /* new menu item */ pl = WMPopFromArray(plMenuNodes); if (wm->Flags & F_RESTART_OTHER) { /* RESTART, somewm */ char buf[1024]; memset(buf, 0, sizeof(buf)); snprintf(buf, sizeof(buf), "%s %s", _("Restart"), wm->Name); WMAddToPLArray(pl, WMCreatePLArray( WMCreatePLString(buf), WMCreatePLString("RESTART"), WMCreatePLString(wm->CmdLine), NULL) ); } else if (wm->Flags & F_RESTART_SELF) {/* RESTART */ WMAddToPLArray(pl, WMCreatePLArray( WMCreatePLString(_("Restart Window Maker")), WMCreatePLString("RESTART"), NULL) ); } else if (wm->Flags & F_QUIT) { /* EXIT */ WMAddToPLArray(pl, WMCreatePLArray( WMCreatePLString(_("Exit Window Maker")), WMCreatePLString("EXIT"), NULL) ); } else { /* plain simple command */ char buf[1024]; memset(buf, 0, sizeof(buf)); if (wm->Flags & F_TERMINAL) /* XXX: quoting! */ snprintf(buf, sizeof(buf), "%s -e \"%s\"", terminal, wm->CmdLine); else snprintf(buf, sizeof(buf), "%s", wm->CmdLine); WMAddToPLArray(pl, WMCreatePLArray( WMCreatePLString(wm->Name), WMCreatePLString("SHEXEC"), WMCreatePLString(buf), NULL) ); } WMAddToArray(plMenuNodes, pl); } *(int *)data = cDepth; return; }