Пример #1
0
void
WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item)
{
    wassertr(W_TabViewItemView(item) != NULL);

    if (tPtr->maxItems == tPtr->itemCount) {
        WMTabViewItem **items;

        items = wrealloc(tPtr->items,
                         sizeof(WMTabViewItem*) * (tPtr->maxItems + 10));
        memset(&items[tPtr->maxItems], 0, sizeof(WMTabViewItem*) * 10);
        tPtr->items = items;
        tPtr->maxItems += 10;
    }

    if (index > tPtr->itemCount)
        index = tPtr->itemCount;

    if (index == 0 && tPtr->items[0]) {
        W_UnmapTabViewItem(tPtr->items[0]);
    }

    if (index < tPtr->itemCount) {
        memmove(tPtr->items + index + 1, tPtr->items + index,
                (tPtr->itemCount - index) * sizeof(WMTabViewItem*));
    }

    tPtr->items[index] = item;

    tPtr->itemCount++;

    recalcTabWidth(tPtr);

    W_SetTabViewItemParent(item, tPtr);

    W_UnmapTabViewItem(item);

    if (tPtr->flags.bordered) {
        W_ReparentView(W_TabViewItemView(item), tPtr->view, 1,
                       tPtr->tabHeight + 1);

        W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width - 3,
                     tPtr->view->size.height - tPtr->tabHeight - 3);
    } else {
        W_ReparentView(W_TabViewItemView(item), tPtr->view, 0,
                       tPtr->tabHeight);

        W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width,
                     tPtr->view->size.height - tPtr->tabHeight);
    }

    if (index == 0) {
        W_MapTabViewItem(item);
    }
    if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
        (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);

    if (W_VIEW_REALIZED(tPtr->view))
        paintTabView(tPtr);
}
Пример #2
0
void WMSetTextFieldText(WMTextField * tPtr, const char *text)
{
	CHECK_CLASS(tPtr, WC_TextField);

	if ((text && strcmp(tPtr->text, text) == 0) || (!text && tPtr->textLen == 0))
		return;

	if (text == NULL) {
		tPtr->text[0] = 0;
		tPtr->textLen = 0;
	} else {
		tPtr->textLen = strlen(text);

		if (tPtr->textLen >= tPtr->bufferSize) {
			tPtr->bufferSize = tPtr->textLen + TEXT_BUFFER_INCR;
			tPtr->text = wrealloc(tPtr->text, tPtr->bufferSize);
		}
		wstrlcpy(tPtr->text, text, tPtr->bufferSize);
	}

	tPtr->cursorPosition = tPtr->selection.position = tPtr->textLen;
	tPtr->viewPosition = 0;
	tPtr->selection.count = 0;

	if (tPtr->view->flags.realized)
		paintTextField(tPtr);
}
Пример #3
0
static void
_expend_on_demand(struct socket_buffer *b, size_t n) {
	size_t num = b->tail.num + n;
	if (num > b->tail.len) {
		b->tail.len += num;
		b->tail.slots = wrealloc(b->tail.slots, sizeof(struct weenet_message *) * b->tail.len);
	}
}
Пример #4
0
/*
 * Reallocate memory block pointed to by iptr in chunks of chunk_size when
 * required_size is greater than value pointed to be allocated_size.
 * Sets value of allocated_size to current allocation.
 */
void * reallocate_block(void *iptr, int *allocated_size, int required_size, int chunk_size) {
    void        *result;

    if (*allocated_size >= required_size)
        return iptr;

    *allocated_size += (((required_size-*allocated_size)/chunk_size)+1)*chunk_size;

    result = wrealloc(iptr, *allocated_size);

    return result;
}
Пример #5
0
/**
 * Add new host (identified by address and port) to the Gnutella host vector.
 */
void
gnet_host_vec_add(gnet_host_vec_t *vec, host_addr_t addr, uint16 port)
{
	g_return_if_fail(vec);

	switch (host_addr_net(addr)) {
	case NET_TYPE_IPV4:
		if (vec->n_ipv4 < 255) {
			size_t size, old_size;
			char *dest;

			old_size = vec->n_ipv4 * sizeof vec->hvec_v4[0];
			size = old_size + sizeof vec->hvec_v4[0];
			vec->hvec_v4 = wrealloc(vec->hvec_v4, old_size, size);

			dest = cast_to_pointer(&vec->hvec_v4[vec->n_ipv4++]);
			poke_be32(&dest[0], host_addr_ipv4(addr));
			poke_le16(&dest[4], port);
		}
		break;
	case NET_TYPE_IPV6:
		if (vec->n_ipv6 < 255) {
			size_t size, old_size;
			char *dest;

			old_size = vec->n_ipv6 * sizeof vec->hvec_v6[0];
			size = old_size + sizeof vec->hvec_v6[0];
			vec->hvec_v6 = wrealloc(vec->hvec_v6, old_size, size);

			dest = cast_to_pointer(&vec->hvec_v6[vec->n_ipv6++]);
			dest = mempcpy(dest, host_addr_ipv6(&addr), 16);
			poke_le16(dest, port);
		}
		break;
	case NET_TYPE_LOCAL:
	case NET_TYPE_NONE:
		break;
	}
}
Пример #6
0
void WDMBufferedLogMessages(int level, char *buffer, int n)
{
    static char *old = NULL;
    static size_t oldn = 0;

    char *rest;

    old = wrealloc(old, oldn + n);
    memcpy(old + oldn, buffer, n);
    oldn += n;

    rest = WDMLogMessages(level, old, oldn);

    oldn -= rest - old;
    memmove(old, rest, oldn);
}
Пример #7
0
void WMInsertTextFieldText(WMTextField * tPtr, const char *text, int position)
{
	int len;

	CHECK_CLASS(tPtr, WC_TextField);

	if (!text)
		return;

	len = strlen(text);

	/* check if buffer will hold the text */
	if (len + tPtr->textLen >= tPtr->bufferSize) {
		tPtr->bufferSize = tPtr->textLen + len + TEXT_BUFFER_INCR;
		tPtr->text = wrealloc(tPtr->text, tPtr->bufferSize);
	}

	if (position < 0 || position >= tPtr->textLen) {
		/* append the text at the end */
		wstrlcat(tPtr->text, text, tPtr->bufferSize);
		tPtr->textLen += len;
		tPtr->cursorPosition += len;
		incrToFit(tPtr);
	} else {
		/* insert text at position */
		memmv(&(tPtr->text[position + len]), &(tPtr->text[position]), tPtr->textLen - position + 1);

		memcpy(&(tPtr->text[position]), text, len);

		tPtr->textLen += len;
		if (position >= tPtr->cursorPosition) {
			tPtr->cursorPosition += len;
			incrToFit2(tPtr);
		} else {
			incrToFit(tPtr);
		}
	}

	paintTextField(tPtr);
}
Пример #8
0
/**
 * Grow token buffer to hold at least ``len'' bytes.
 */
static void
grow_token(strtok_t *s, size_t len)
{
	strtok_check(s);
	g_assert(len > 0);
	g_assert(len > s->len);

	if (s->len) {
		size_t offset;

		g_assert(s->t != NULL);

		offset = s->t - s->token;
		s->token = wrealloc(s->token, s->len, len);
		s->t = s->token + offset;
	} else {
		s->token = walloc(len);
		s->t = s->token;
	}

	s->len = len;
}
Пример #9
0
/**
 * Set the page cache size.
 * @return 0 if OK, -1 on failure with errno set.
 */
int
setcache(DBM *db, long pages)
{
	struct lru_cache *cache = db->cache;
	bool wdelay;

	sdbm_lru_check(cache);

	if (pages <= 0) {
		errno = EINVAL;
		return -1;
	}

	if (NULL == cache)
		return init_cache(db, pages, FALSE);

	/*
	 * Easiest case: the size identical.
	 */

	if (pages == cache->pages)
		return 0;

	/*
	 * Cache size is changed.
	 *
	 * This means the arena will be reallocated, so we must invalidate the
	 * current db->pagbuf pointer, which lies within the old arena.  It is
	 * sufficient to reset db->pagbno, forcing a reload from the upper layers.
	 * Note than when the cache size is enlarged, the old page is still cached
	 * so reloading will be just a matter of recomputing db->pagbuf.  We could
	 * do so here, but cache size changes should only be infrequent.
	 *
	 * We also reset all the cache statistics, since a different cache size
	 * will imply a different set of hit/miss ratio.
	 */

	db->pagbno = -1;		/* Current page address will become invalid */
	db->pagbuf = NULL;

	if (common_stats) {
		s_info("sdbm: \"%s\" LRU cache size %s from %ld page%s to %ld",
			sdbm_name(db), pages > cache->pages ? "increased" : "decreased",
			cache->pages, plural(cache->pages), pages);
		log_lrustats(db);
	}

	cache->rhits = cache->rmisses = 0;
	cache->whits = cache->wmisses = 0;

	/*
	 * Straightforward: the size is increased.
	 */

	if (pages > cache->pages) {
		char *new_arena = vmm_alloc(pages * DBM_PBLKSIZ);
		if (NULL == new_arena)
			return -1;
		memmove(new_arena, cache->arena, cache->pages * DBM_PBLKSIZ);
		vmm_free(cache->arena, cache->pages * DBM_PBLKSIZ);
		cache->arena = new_arena;
		cache->dirty = wrealloc(cache->dirty, cache->pages, pages);
		cache->numpag = wrealloc(cache->numpag,
			cache->pages * sizeof(long), pages * sizeof(long));
		cache->pages = pages;
		return 0;
	}

	/*
	 * Difficult: the size is decreased.
	 *
	 * The current page buffer could point in a cache area that is going
	 * to disappear, and the internal data structures must forget about
	 * all the old indices that are greater than the new limit.
	 *
	 * We do not try to optimize anything here, as this call should happen
	 * only infrequently: we flush the current cache (in case there are
	 * deferred writes), destroy the LRU cache data structures, recreate a
	 * new one and invalidate the current DB page.
	 */

	wdelay = cache->write_deferred;
	flush_dirtypag(db);
	free_cache(cache);
	return setup_cache(cache, pages, wdelay);
}
Пример #10
0
/*
    Process a form request. Returns 1 always to indicate it handled the URL
 */
static bool cgiHandler(Webs *wp)
{
    Cgi         *cgip;
    WebsKey     *s;
    char        cgiPrefix[BIT_GOAHEAD_LIMIT_FILENAME], *stdIn, *stdOut, cwd[BIT_GOAHEAD_LIMIT_FILENAME];
    char        *cp, *cgiName, *cgiPath, **argp, **envp, **ep, *tok, *query, *dir, *extraPath;
    int         n, envpsize, argpsize, pHandle, cid;

    assert(websValid(wp));
    
    websSetEnv(wp);

    /*
        Extract the form name and then build the full path name.  The form name will follow the first '/' in path.
     */
    scopy(cgiPrefix, sizeof(cgiPrefix), wp->path);
    if ((cgiName = strchr(&cgiPrefix[1], '/')) == NULL) {
        websError(wp, HTTP_CODE_NOT_FOUND, "Missing CGI name");
        return 1;
    }
    *cgiName++ = '\0';

    getcwd(cwd, BIT_GOAHEAD_LIMIT_FILENAME);
    dir = wp->route->dir ? wp->route->dir : cwd;
    chdir(dir);
    
    extraPath = 0;
    if ((cp = strchr(cgiName, '/')) != NULL) {
        extraPath = sclone(cp);
        *cp = '\0';
        websSetVar(wp, "PATH_INFO", extraPath);
        websSetVarFmt(wp, "PATH_TRANSLATED", "%s%s%s", dir, cgiPrefix, extraPath);
        wfree(extraPath);
    } else {
        websSetVar(wp, "PATH_INFO", "");
        websSetVar(wp, "PATH_TRANSLATED", "");        
    }
    cgiPath = sfmt("%s%s/%s", dir, cgiPrefix, cgiName);
    websSetVarFmt(wp, "SCRIPT_NAME", "%s/%s", cgiPrefix, cgiName);
    websSetVar(wp, "SCRIPT_FILENAME", cgiPath);
    
/*
    See if the file exists and is executable.  If not error out.  Don't do this step for VxWorks, since the module
    may already be part of the OS image, rather than in the file system.
*/
#if !VXWORKS
    {
        WebsStat sbuf;
        if (stat(cgiPath, &sbuf) != 0 || (sbuf.st_mode & S_IFREG) == 0) {
            error("Cannot find CGI program: ", cgiPath);
            websError(wp, HTTP_CODE_NOT_FOUND | WEBS_NOLOG, "CGI program file does not exist");
            wfree(cgiPath);
            return 1;
        }
#if BIT_WIN_LIKE
        if (strstr(cgiPath, ".exe") == NULL && strstr(cgiPath, ".bat") == NULL)
#else
        if (access(cgiPath, X_OK) != 0)
#endif
        {
            websError(wp, HTTP_CODE_NOT_FOUND, "CGI process file is not executable");
            wfree(cgiPath);
            return 1;
        }
    }
#endif /* ! VXWORKS */
    /*
        Build command line arguments.  Only used if there is no non-encoded = character.  This is indicative of a ISINDEX
        query.  POST separators are & and others are +.  argp will point to a walloc'd array of pointers.  Each pointer
        will point to substring within the query string.  This array of string pointers is how the spawn or exec routines
        expect command line arguments to be passed.  Since we don't know ahead of time how many individual items there are
        in the query string, the for loop includes logic to grow the array size via wrealloc.
     */
    argpsize = 10;
    argp = walloc(argpsize * sizeof(char *));
    *argp = cgiPath;
    n = 1;
    query = 0;

    if (strchr(wp->query, '=') == NULL) {
        query = sclone(wp->query);
        websDecodeUrl(query, query, strlen(query));
        for (cp = stok(query, " ", &tok); cp != NULL; ) {
            *(argp+n) = cp;
            trace(5, "ARG[%d] %s", n, argp[n-1]);
            n++;
            if (n >= argpsize) {
                argpsize *= 2;
                argp = wrealloc(argp, argpsize * sizeof(char *));
            }
            cp = stok(NULL, " ", &tok);
        }
    }
    *(argp+n) = NULL;

    /*
        Add all CGI variables to the environment strings to be passed to the spawned CGI process. This includes a few
        we don't already have in the symbol table, plus all those that are in the vars symbol table. envp will point
        to a walloc'd array of pointers. Each pointer will point to a walloc'd string containing the keyword value pair
        in the form keyword=value. Since we don't know ahead of time how many environment strings there will be the for
        loop includes logic to grow the array size via wrealloc.
     */
    envpsize = 64;
    envp = walloc(envpsize * sizeof(char*));
    for (n = 0, s = hashFirst(wp->vars); s != NULL; s = hashNext(wp->vars, s)) {
        if (s->content.valid && s->content.type == string &&
            strcmp(s->name.value.string, "REMOTE_HOST") != 0 &&
            strcmp(s->name.value.string, "HTTP_AUTHORIZATION") != 0) {
            envp[n++] = sfmt("%s=%s", s->name.value.string, s->content.value.string);
            trace(5, "Env[%d] %s", n, envp[n-1]);
            if (n >= envpsize) {
                envpsize *= 2;
                envp = wrealloc(envp, envpsize * sizeof(char *));
            }
        }
    }
    *(envp+n) = NULL;

    /*
        Create temporary file name(s) for the child's stdin and stdout. For POST data the stdin temp file (and name)
        should already exist.  
     */
    if (wp->cgiStdin == NULL) {
        wp->cgiStdin = websGetCgiCommName();
    } 
    stdIn = wp->cgiStdin;
    stdOut = websGetCgiCommName();
    /*
        Now launch the process.  If not successful, do the cleanup of resources.  If successful, the cleanup will be
        done after the process completes.  
     */
    if ((pHandle = launchCgi(cgiPath, argp, envp, stdIn, stdOut)) == -1) {
        websError(wp, HTTP_CODE_INTERNAL_SERVER_ERROR, "failed to spawn CGI task");
        for (ep = envp; *ep != NULL; ep++) {
            wfree(*ep);
        }
        wfree(cgiPath);
        wfree(argp);
        wfree(envp);
        wfree(stdOut);
        wfree(query);

    } else {
        /*
            If the spawn was successful, put this wp on a queue to be checked for completion.
         */
        cid = wallocObject(&cgiList, &cgiMax, sizeof(Cgi));
        cgip = cgiList[cid];
        cgip->handle = pHandle;
        cgip->stdIn = stdIn;
        cgip->stdOut = stdOut;
        cgip->cgiPath = cgiPath;
        cgip->argp = argp;
        cgip->envp = envp;
        cgip->wp = wp;
        cgip->fplacemark = 0;
        wfree(query);
    }
    /*
        Restore the current working directory after spawning child CGI
     */
    chdir(cwd);
    return 1;
}
Пример #11
0
void wWorkspaceForceChange(WScreen * scr, int workspace)
{
	WWindow *tmp, *foc = NULL, *foc2 = NULL;
	WWindow **toUnmap;
	int toUnmapSize, toUnmapCount;

	if (workspace >= MAX_WORKSPACES || workspace < 0)
		return;

	SendHelperMessage(scr, 'C', workspace + 1, NULL);

	if (workspace > w_global.workspace.count - 1)
		wWorkspaceMake(scr, workspace - w_global.workspace.count + 1);

	wClipUpdateForWorkspaceChange(scr, workspace);

	w_global.workspace.last_used = w_global.workspace.current;
	w_global.workspace.current = workspace;

	wWorkspaceMenuUpdate(w_global.workspace.menu);

	wWorkspaceMenuUpdate(w_global.clip.ws_menu);

	toUnmapSize = 16;
	toUnmapCount = 0;
	toUnmap = wmalloc(toUnmapSize * sizeof(WWindow *));

	if ((tmp = scr->focused_window) != NULL) {
		if ((IS_OMNIPRESENT(tmp) && (tmp->flags.mapped || tmp->flags.shaded) &&
		     !WFLAGP(tmp, no_focusable)) || tmp->flags.changing_workspace) {
			foc = tmp;
		}

		/* foc2 = tmp; will fix annoyance with gnome panel
		 * but will create annoyance for every other application
		 */
		while (tmp) {
			if (tmp->frame->workspace != workspace && !tmp->flags.selected) {
				/* unmap windows not on this workspace */
				if ((tmp->flags.mapped || tmp->flags.shaded) &&
				    !IS_OMNIPRESENT(tmp) && !tmp->flags.changing_workspace) {
					if (toUnmapCount == toUnmapSize)
					{
						toUnmapSize *= 2;
						toUnmap = wrealloc(toUnmap, toUnmapSize * sizeof(WWindow *));
					}
					toUnmap[toUnmapCount++] = tmp;
				}
				/* also unmap miniwindows not on this workspace */
				if (!wPreferences.sticky_icons && tmp->flags.miniaturized &&
				    tmp->icon && !IS_OMNIPRESENT(tmp)) {
					XUnmapWindow(dpy, tmp->icon->core->window);
					tmp->icon->mapped = 0;
				}
				/* update current workspace of omnipresent windows */
				if (IS_OMNIPRESENT(tmp)) {
					WApplication *wapp = wApplicationOf(tmp->main_window);

					tmp->frame->workspace = workspace;

					if (wapp) {
						wapp->last_workspace = workspace;
					}
					if (!foc2 && (tmp->flags.mapped || tmp->flags.shaded)) {
						foc2 = tmp;
					}
				}
			} else {
				/* change selected windows' workspace */
				if (tmp->flags.selected) {
					wWindowChangeWorkspace(tmp, workspace);
					if (!tmp->flags.miniaturized && !foc) {
						foc = tmp;
					}
				} else {
					if (!tmp->flags.hidden) {
						if (!(tmp->flags.mapped || tmp->flags.miniaturized)) {
							/* remap windows that are on this workspace */
							wWindowMap(tmp);
							if (!foc && !WFLAGP(tmp, no_focusable)) {
								foc = tmp;
							}
						}
						/* Also map miniwindow if not omnipresent */
						if (!wPreferences.sticky_icons &&
						    tmp->flags.miniaturized && !IS_OMNIPRESENT(tmp) && tmp->icon) {
							tmp->icon->mapped = 1;
							XMapWindow(dpy, tmp->icon->core->window);
						}
					}
				}
			}
			tmp = tmp->prev;
		}

		while (toUnmapCount > 0)
		{
			wWindowUnmap(toUnmap[--toUnmapCount]);
		}
		wfree(toUnmap);

		/* Gobble up events unleashed by our mapping & unmapping.
		 * These may trigger various grab-initiated focus &
		 * crossing events. However, we don't care about them,
		 * and ignore their focus implications altogether to avoid
		 * flicker.
		 */
		scr->flags.ignore_focus_events = 1;
		ProcessPendingEvents();
		scr->flags.ignore_focus_events = 0;

		if (!foc)
			foc = foc2;

		if (scr->focused_window->flags.mapped && !foc) {
			foc = scr->focused_window;
		}
		if (wPreferences.focus_mode == WKF_CLICK) {
			wSetFocusTo(scr, foc);
		} else {
			unsigned int mask;
			int foo;
			Window bar, win;
			WWindow *tmp;

			tmp = NULL;
			if (XQueryPointer(dpy, scr->root_win, &bar, &win, &foo, &foo, &foo, &foo, &mask)) {
				tmp = wWindowFor(win);
			}

			/* If there's a window under the pointer, focus it.
			 * (we ate all other focus events above, so it's
			 * certainly not focused). Otherwise focus last
			 * focused, or the root (depending on sloppiness)
			 */
			if (!tmp && wPreferences.focus_mode == WKF_SLOPPY) {
				wSetFocusTo(scr, foc);
			} else {
				wSetFocusTo(scr, tmp);
			}
		}
	}

	/* We need to always arrange icons when changing workspace, even if
	 * no autoarrange icons, because else the icons in different workspaces
	 * can be superposed.
	 * This can be avoided if appicons are also workspace specific.
	 */
	if (!wPreferences.sticky_icons)
		wArrangeIcons(scr, False);

	if (scr->dock)
		wAppIconPaint(scr->dock->icon_array[0]);

	if (!wPreferences.flags.noclip && (w_global.workspace.array[workspace]->clip->auto_collapse ||
					   w_global.workspace.array[workspace]->clip->auto_raise_lower)) {
		/* to handle enter notify. This will also */
		XUnmapWindow(dpy, w_global.clip.icon->icon->core->window);
		XMapWindow(dpy, w_global.clip.icon->icon->core->window);
	}
	else if (w_global.clip.icon != NULL) {
		wClipIconPaint();
	}
	wScreenUpdateUsableArea(scr);
	wNETWMUpdateDesktop(scr);
	showWorkspaceName(scr, workspace);

	WMPostNotificationName(WMNWorkspaceChanged, scr, (void *)(uintptr_t) workspace);

	/*   XSync(dpy, False); */
}