static void registerDescriptionList(WMScreen * scr, WMView * view, WMArray * operationArray) { char *text, *textListItem, *textList; int count = WMGetArrayItemCount(operationArray); int i; int size = 0; /* size of XA_STRING info */ for (i = 0; i < count; i++) { size += strlen(WMGetDragOperationItemText(WMGetFromArray(operationArray, i))) + 1 /* NULL */; } /* create text list */ textList = wmalloc(size); textListItem = textList; for (i = 0; i < count; i++) { text = WMGetDragOperationItemText(WMGetFromArray(operationArray, i)); wstrlcpy(textListItem, text, size); /* to next text offset */ textListItem = &(textListItem[strlen(textListItem) + 1]); } XChangeProperty(scr->display, WMViewXID(view), scr->xdndActionDescriptionAtom, XA_STRING, XDND_ACTION_DESCRIPTION_FORMAT, PropModeReplace, (unsigned char *)textList, size); }
static Atom *getTypeAtomList(WMScreen * scr, WMView * view, int *count) { WMArray *types; Atom *typeAtoms; int i; types = view->dragSourceProcs->dropDataTypes(view); if (types != NULL) { *count = WMGetArrayItemCount(types); if (*count > 0) { typeAtoms = wmalloc((*count) * sizeof(Atom)); for (i = 0; i < *count; i++) { typeAtoms[i] = XInternAtom(scr->display, WMGetFromArray(types, i), False); } /* WMFreeArray(types); */ return typeAtoms; } /* WMFreeArray(types); */ } *count = 1; typeAtoms = wmalloc(sizeof(Atom)); *typeAtoms = None; return typeAtoms; }
WMMaskedEvents* WMMaskEvents(WMView* view) { W_MaskedEvents *mask; unsigned int i; Bool changed = False; mask = wmalloc(sizeof(W_MaskedEvents)); mask->view = view; mask->procs = WMCreateArray(0); mask->data = WMCreateArray(0); for (i = 0; i < WMGetArrayItemCount(W_GetViewEventHandlers(view)); i++) { W_EventHandler *h = (W_EventHandler*) WMGetFromArray(W_GetViewEventHandlers(view), i); if (h->eventMask == (ButtonPressMask|ButtonReleaseMask| EnterWindowMask|LeaveWindowMask|ButtonMotionMask)) { WMAddToArray(mask->procs, h->proc); WMAddToArray(mask->data, h->clientData); /* we change only the first handler to our one, because they seem to be processed upside-down and we want the dnd-handler to be processed first. */ if (changed == False) { h->proc = W_MaskedEventHandler; h->clientData = (void*) mask; changed = True; } else { WMDeleteEventHandler(view, h->eventMask, h->proc, h->clientData); } } } return mask; }
static WMPropList *retainPropListByCount(WMPropList * plist, int count) { WMPropList *key, *value; WMHashEnumerator e; int i; plist->retainCount += count; switch (plist->type) { case WPLString: case WPLData: break; case WPLArray: for (i = 0; i < WMGetArrayItemCount(plist->d.array); i++) { retainPropListByCount(WMGetFromArray(plist->d.array, i), count); } break; case WPLDictionary: e = WMEnumerateHashTable(plist->d.dict); while (WMNextHashEnumeratorItemAndKey(&e, (void **)&value, (void **)&key)) { retainPropListByCount(key, count); retainPropListByCount(value, count); } break; default: wwarning(_("Used proplist functions on non-WMPropLists objects")); wassertrv(False, NULL); break; } return plist; }
void W_MaskedEventHandler(XEvent *event, void *data) { W_MaskedEvents *events = (W_MaskedEvents*)data; WMEventProc *proc = NULL; unsigned int i; for (i = 0; i < WMGetArrayItemCount(events->procs); i++) { if (WMIsDraggingFromView(events->view) == False) { proc = WMGetFromArray(events->procs, i); (*proc)(event, WMGetFromArray(events->data, i)); } else { /* *cough* evil *cough* hack... */ if (W_CLASS(events->view->self) == WC_List) { ((W_List*)(events->view->self))->flags.buttonWasPressed = 0; ((W_List*)(events->view->self))->flags.buttonPressed = 0; } } } }
static void sortLeavesForNode(WMTreeNode * aNode, WMCompareDataProc * comparer) { int i; if (!aNode->leaves) return; WMSortArray(aNode->leaves, comparer); for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) { sortLeavesForNode(WMGetFromArray(aNode->leaves, i), comparer); } }
static void updateNodeDepth(WMTreeNode * aNode, int depth) { int i; aNode->depth = depth; if (aNode->leaves) { for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) { updateNodeDepth(WMGetFromArray(aNode->leaves, i), depth + 1); } } }
struct display *FindDisplayByAddress(XdmcpNetaddr addr, int addrlen, CARD16 displayNumber) { if (displays != NULL) { int i; struct _matchAddress a; a.addr = addr; a.addrlen = addrlen; a.displayNumber = displayNumber; if ((i = WMFindInArray(displays, (WMMatchDataProc *) matchAddress, &a)) != WANotFound) return WMGetFromArray(displays, i); } return NULL; }
static void releasePropListByCount(WMPropList * plist, int count) { WMPropList *key, *value; WMHashEnumerator e; int i; plist->retainCount -= count; switch (plist->type) { case WPLString: if (plist->retainCount < 1) { wfree(plist->d.string); wfree(plist); } break; case WPLData: if (plist->retainCount < 1) { WMReleaseData(plist->d.data); wfree(plist); } break; case WPLArray: for (i = 0; i < WMGetArrayItemCount(plist->d.array); i++) { releasePropListByCount(WMGetFromArray(plist->d.array, i), count); } if (plist->retainCount < 1) { WMFreeArray(plist->d.array); wfree(plist); } break; case WPLDictionary: e = WMEnumerateHashTable(plist->d.dict); while (WMNextHashEnumeratorItemAndKey(&e, (void **)&value, (void **)&key)) { releasePropListByCount(key, count); releasePropListByCount(value, count); } if (plist->retainCount < 1) { WMFreeHashTable(plist->d.dict); wfree(plist); } break; default: wwarning(_("Used proplist functions on non-WMPropLists objects")); wassertr(False); break; } }
static void registerOperationList(WMScreen * scr, WMView * view, WMArray * operationArray) { Atom *actionList; WMDragOperationType operation; int count = WMGetArrayItemCount(operationArray); int i; actionList = wmalloc(sizeof(Atom) * count); for (i = 0; i < count; i++) { operation = WMGetDragOperationItemType(WMGetFromArray(operationArray, i)); actionList[i] = W_OperationToAction(scr, operation); } XChangeProperty(scr->display, WMViewXID(view), scr->xdndActionListAtom, XA_ATOM, XDND_PROPERTY_FORMAT, PropModeReplace, (unsigned char *)actionList, count); }
void WMTreeWalk(WMTreeNode * aNode, WMTreeWalkProc * walk, void *data, Bool DepthFirst) { int i; WMTreeNode *leaf; wassertr(aNode != NULL); if (DepthFirst) (*walk)(aNode, data); if (aNode->leaves) { for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) { leaf = (WMTreeNode *)WMGetFromArray(aNode->leaves, i); WMTreeWalk(leaf, walk, data, DepthFirst); } } if (!DepthFirst) (*walk)(aNode, data); }
static WMTreeNode *findNodeInTree(WMTreeNode * aNode, WMMatchDataProc * match, void *cdata, int limit) { if (match == NULL && aNode->data == cdata) return aNode; else if (match && (*match) (aNode->data, cdata)) return aNode; if (aNode->leaves && limit != 0) { WMTreeNode *leaf; int i; for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) { leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i), match, cdata, limit > 0 ? limit - 1 : limit); if (leaf) return leaf; } } return NULL; }
int showCrashDialog(int sig) { int crashAction; dpy = XOpenDisplay(NULL); if (dpy) { /* XXX TODO make sure that window states are saved and restored via netwm */ XGrabServer(dpy); crashAction = wShowCrashingDialogPanel(sig); XCloseDisplay(dpy); dpy = NULL; } else { wsyserror(_("cannot open connection for crashing dialog panel. Aborting.")); crashAction = WMAbort; } if (crashAction == WMStartAlternate) { int i; wmessage(_("trying to start alternate window manager...")); for (i=0; i<WMGetArrayItemCount(wPreferences.fallbackWMs); i++) { Restart(WMGetFromArray(wPreferences.fallbackWMs, i), False); } wfatal(_("failed to start alternate window manager. Aborting.")); return 0; } else if (crashAction == WMAbort) return 0; else return 1; }
/* * This functions will handle input events on all registered file descriptors. * Input: * - waitForInput - True if we want the function to wait until an event * appears on a file descriptor we watch, False if we * want the function to immediately return if there is * no data available on the file descriptors we watch. * - inputfd - Extra input file descriptor to watch for input. * This is only used when called from wevent.c to watch * on ConnectionNumber(dpy) to avoid blocking of X events * if we wait for input from other file handlers. * Output: * if waitForInput is False, the function will return False if there are no * input handlers registered, or if there is no data * available on the registered ones, and will return True * if there is at least one input handler that has data * available. * if waitForInput is True, the function will return False if there are no * input handlers registered, else it will block until an * event appears on one of the file descriptors it watches * and then it will return True. * * If the retured value is True, the input handlers for the corresponding file * descriptors are also called. * * Parametersshould be passed like this: * - from wevent.c: * waitForInput - apropriate value passed by the function who called us * inputfd = ConnectionNumber(dpy) * - from wutil.c: * waitForInput - apropriate value passed by the function who called us * inputfd = -1 * */ Bool W_HandleInputEvents(Bool waitForInput, int inputfd) { #if defined(HAVE_POLL) && defined(HAVE_POLL_H) && !defined(HAVE_SELECT) struct poll fd *fds; InputHandler *handler; int count, timeout, nfds, i, extrafd; extrafd = (inputfd < 0) ? 0 : 1; if (inputHandler) nfds = WMGetArrayItemCount(inputHandler); else nfds = 0; if (!extrafd && nfds==0) { W_FlushASAPNotificationQueue(); return False; } fds = wmalloc((nfds+extrafd) * sizeof(struct pollfd)); if (extrafd) { /* put this to the end of array to avoid using ranges from 1 to nfds+1 */ fds[nfds].fd = inputfd; fds[nfds].events = POLLIN; } /* use WM_ITERATE_ARRAY() here */ for (i = 0; i<nfds; i++) { handler = WMGetFromArray(inputHandler, i); fds[i].fd = handler->fd; fds[i].events = 0; if (handler->mask & WIReadMask) fds[i].events |= POLLIN; if (handler->mask & WIWriteMask) fds[i].events |= POLLOUT; #if 0 /* FIXME */ if (handler->mask & WIExceptMask) FD_SET(handler->fd, &eset); #endif } /* * Setup the timeout to the estimated time until the * next timer expires. */ if (!waitForInput) { timeout = 0; } else if (timerPending()) { struct timeval tv; delayUntilNextTimerEvent(&tv); timeout = tv.tv_sec * 1000 + tv.tv_usec / 1000; } else { timeout = -1; } count = poll(fds, nfds+extrafd, timeout); if (count>0 && nfds>0) { WMArray *handlerCopy = WMDuplicateArray(inputHandler); int mask; /* use WM_ITERATE_ARRAY() here */ for (i=0; i<nfds; i++) { handler = WMGetFromArray(handlerCopy, i); /* check if the handler still exist or was removed by a callback */ if (WMGetFirstInArray(inputHandler, handler) == WANotFound) continue; mask = 0; if ((handler->mask & WIReadMask) && (fds[i].revents & (POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI))) mask |= WIReadMask; if ((handler->mask & WIWriteMask) && (fds[i].revents & (POLLOUT | POLLWRBAND))) mask |= WIWriteMask; if ((handler->mask & WIExceptMask) && (fds[i].revents & (POLLHUP | POLLNVAL | POLLERR))) mask |= WIExceptMask; if (mask!=0 && handler->callback) { (*handler->callback)(handler->fd, mask, handler->clientData); } } WMFreeArray(handlerCopy); } wfree(fds); W_FlushASAPNotificationQueue(); return (count > 0); #else #ifdef HAVE_SELECT struct timeval timeout; struct timeval *timeoutPtr; fd_set rset, wset, eset; int maxfd, nfds, i; int count; InputHandler *handler; if (inputHandler) nfds = WMGetArrayItemCount(inputHandler); else nfds = 0; if (inputfd<0 && nfds==0) { W_FlushASAPNotificationQueue(); return False; } FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset); if (inputfd < 0) { maxfd = 0; } else { FD_SET(inputfd, &rset); maxfd = inputfd; } /* use WM_ITERATE_ARRAY() here */ for (i=0; i<nfds; i++) { handler = WMGetFromArray(inputHandler, i); if (handler->mask & WIReadMask) FD_SET(handler->fd, &rset); if (handler->mask & WIWriteMask) FD_SET(handler->fd, &wset); if (handler->mask & WIExceptMask) FD_SET(handler->fd, &eset); if (maxfd < handler->fd) maxfd = handler->fd; } /* * Setup the timeout to the estimated time until the * next timer expires. */ if (!waitForInput) { SET_ZERO(timeout); timeoutPtr = &timeout; } else if (timerPending()) { delayUntilNextTimerEvent(&timeout); timeoutPtr = &timeout; } else { timeoutPtr = (struct timeval*)0; } count = select(1 + maxfd, &rset, &wset, &eset, timeoutPtr); if (count>0 && nfds>0) { WMArray *handlerCopy = WMDuplicateArray(inputHandler); int mask; /* use WM_ITERATE_ARRAY() here */ for (i=0; i<nfds; i++) { handler = WMGetFromArray(handlerCopy, i); /* check if the handler still exist or was removed by a callback */ if (WMGetFirstInArray(inputHandler, handler) == WANotFound) continue; mask = 0; if ((handler->mask & WIReadMask) && FD_ISSET(handler->fd, &rset)) mask |= WIReadMask; if ((handler->mask & WIWriteMask) && FD_ISSET(handler->fd, &wset)) mask |= WIWriteMask; if ((handler->mask & WIExceptMask) && FD_ISSET(handler->fd, &eset)) mask |= WIExceptMask; if (mask!=0 && handler->callback) { (*handler->callback)(handler->fd, mask, handler->clientData); } } WMFreeArray(handlerCopy); } W_FlushASAPNotificationQueue(); return (count > 0); #else /* not HAVE_SELECT, not HAVE_POLL */ # error Neither select nor poll. You lose. #endif /* HAVE_SELECT */ #endif /* HAVE_POLL */ }
WMArray *WMGetBrowserPaths(WMBrowser * bPtr) { int column, i, k, size, selNo; char *path; size_t slen; WMListItem *item, *lastItem; WMArray *paths, *items; column = bPtr->usedColumnCount - 1; if (column < 0) { paths = WMCreateArrayWithDestructor(1, wfree); WMAddToArray(paths, wstrdup(bPtr->pathSeparator)); return paths; } items = WMGetListSelectedItems(bPtr->columns[column]); selNo = WMGetArrayItemCount(items); paths = WMCreateArrayWithDestructor(selNo, wfree); if (selNo <= 1) { WMAddToArray(paths, WMGetBrowserPath(bPtr)); return paths; } /* calculate size of buffer */ size = 0; for (i = 0; i < column; i++) { item = WMGetListSelectedItem(bPtr->columns[i]); if (!item) break; size += strlen(item->text); } size += (column + 1) * strlen(bPtr->pathSeparator) + 1; for (k = 0; k < selNo; k++) { /* get the path */ lastItem = WMGetFromArray(items, k); slen = size + (lastItem != NULL ? strlen(lastItem->text) : 0); path = wmalloc(slen); /* ignore first `/' */ for (i = 0; i <= column; i++) { if (wstrlcat(path, bPtr->pathSeparator, slen) >= slen) { wfree(path); WMFreeArray(paths); return NULL; } if (i == column) { item = lastItem; } else { item = WMGetListSelectedItem(bPtr->columns[i]); } if (!item) break; if (wstrlcat(path, item->text, slen) >= slen) { wfree(path); return NULL; } } WMAddToArray(paths, path); } return paths; }
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; }