Esempio n. 1
0
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);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
      }
    }
  }
}
Esempio n. 6
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);
	}
}
Esempio n. 7
0
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);
		}
	}
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
	}
}
Esempio n. 10
0
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);
}
Esempio n. 11
0
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);
}
Esempio n. 12
0
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;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
/*
 * 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 */
}
Esempio n. 15
0
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;
}
Esempio n. 16
0
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;
}