예제 #1
0
/**
 * \brief Apply the update structure to the current configuration and execute
 *   callbacks (create/update/delete) on channels/profiles
 * \note After update, the \p update structure is automatically freed.
 * \param[in,out] mgr    Event manager
 * \param[in]     update Update structure
 */
static void
pevents_update_apply(pevents_t *mgr, struct pevents_update *update)
{
	// Copy callbacks from old channels/profiles to new channels/profiles
	update->profiles.cbs = mgr->profiles.cbs;
	update->channels.cbs = mgr->channels.cbs;

	// Call "on_delete" callbacks on OLD profiles/channels
	group_on_delete(&mgr->profiles);
	group_on_delete(&mgr->channels);

	// Call "on_update" callbacks on successfully mapped profiles/channels
	group_on_update(&update->profiles, update->prfl_flags);
	group_on_update(&update->channels, update->chnl_flags);

	// Call "on_create" callbacks on NEW profiles/channels
	group_on_create(&update->profiles);
	group_on_create(&update->channels);

	// Delete old information about channels/profiles and apply the update
	group_deinit(&mgr->profiles);
	group_deinit(&mgr->channels);
	mgr->profiles = update->profiles;
	mgr->channels = update->channels;

	// Cleanup after the update
	bitset_clear(mgr->profiles.bitset);
	bitset_clear(mgr->channels.bitset);

	free(update->chnl_flags);
	free(update->prfl_flags);
	free(update);
}
예제 #2
0
/**
 * \brief Delete an update structure
 *
 * Free internal auxiliary structures and then delete the structure.
 * \param[in,out] update Pointer to the structure
 */
static void
pevents_update_delete(struct pevents_update *update)
{
	group_deinit(&update->channels);
	group_deinit(&update->profiles);

	free(update->chnl_flags);
	free(update->prfl_flags);

	free(update);
}
예제 #3
0
void
pevents_destroy(pevents_t *mgr)
{
	// Call on "on_delete" callbacks on all profiles and channels
	bitset_clear(mgr->profiles.bitset);
	bitset_clear(mgr->channels.bitset);

	group_on_delete(&mgr->profiles);
	group_on_delete(&mgr->channels);

	// Delete internal structures for profiles and channels
	group_deinit(&mgr->profiles);
	group_deinit(&mgr->channels);

	free(mgr);
}
예제 #4
0
pevents_t *
pevents_create(struct pevent_cb_set profiles, struct pevent_cb_set channels)
{
	pevents_t *events = calloc(1, sizeof(*events));
	if (!events) {
		MSG_ERROR(msg_module, "Unable to allocate memory (%s:%d)",
				__FILE__, __LINE__);
		return NULL;
	}

	/* Initialize an internal structures. Because we don't have information
	 * about profiles/channels we should prepare empty structures.
	 * However, pre-allocation for "0" items is not suitable, so we use "1".
	 */
	if (group_init(&events->profiles, 1)) {
		free(events);
		return NULL;
	}

	if (group_init(&events->channels, 1)) {
		group_deinit(&events->profiles);
		free(events);
		return NULL;
	}

	events->channels.cbs = channels;
	events->profiles.cbs = profiles;
	return events;
}
예제 #5
0
/**
 * \brief Create a new update structure and parse a new profile tree
 *
 * Returned structure is prepared for mapping old channels/profiles to new
 * channels/profiles (those are store in this update structure).
 * \param[in] mgr          Event manager
 * \param[in] tree_root    Root profile of the new profile tree
 * \return On success returns a pointer to the structure. Otherwise (memory
 *   allocation error) returns NULL.
 */
static struct pevents_update *
pevents_update_create(pevents_t *mgr, void *tree_root)
{
	struct pevents_update *update;
	update = (struct pevents_update *) calloc(1, sizeof(*update));
	if (!update) {
		MSG_ERROR(msg_module, "Unable to allocate memory (%s:%d)",
			__FILE__, __LINE__);
		return NULL;
	}

	struct pevents_group *chnl_grp = &update->channels;
	struct pevents_group *prfl_grp = &update->profiles;

	/* Prepare hints (expected number of channels/profiles)
	 * Helps to prevent expensive reallocations. */
	size_t profile_hint = mgr->profiles.all_size + PEVENTS_HINT_OVERLAP;
	size_t channel_hint = mgr->channels.all_size + PEVENTS_HINT_OVERLAP;

	if (profile_hint < PEVENTS_HINT_PROFILE) {
		profile_hint = PEVENTS_HINT_PROFILE;
	}

	if (channel_hint < PEVENTS_HINT_CHANNELS) {
		channel_hint = PEVENTS_HINT_CHANNELS;
	}

	// Initialize groups for channels and profiles
	if (group_init(prfl_grp, profile_hint)) {
		free(update);
		return NULL;
	}

	if (group_init(chnl_grp, channel_hint)) {
		group_deinit(prfl_grp);
		free(update);
		return NULL;
	}

	// Parse the profile tree
	if (pevents_update_parse_tree(update, tree_root)) {
		pevents_update_delete(update);
		return NULL;
	}

	// Set user global variables
	for (size_t i = 0; i < chnl_grp->all_size; ++i) {
		struct pevents_item *item = group_item_at(chnl_grp, i);
		item->ctx.user.global = mgr->user_global;
	}

	for (size_t i = 0; i < prfl_grp->all_size; ++i) {
		struct pevents_item *item = group_item_at(prfl_grp, i);
		item->ctx.user.global = mgr->user_global;
	}

	// Success
	return update;
}
예제 #6
0
void groupws_deinit(WGroupWS *ws)
{
    extl_unref_table(ws->initial_outputs);

    screen_unnotify_if_workspace(ws);

    group_deinit(&(ws->grp));
}