<commit_before>/* Copyright (c) 2012, <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "bspwm.h"
#include "desktop.h"
#include "history.h"
#include "messages.h"
#include "monitor.h"
#include "tree.h"
#include "query.h"

void query_monitors(coordinates_t loc, domain_t dom, FILE *rsp)
{
	for (monitor_t *m = mon_head; m != NULL; m = m->next) {
		if (loc.monitor != NULL && m != loc.monitor)
			continue;
		if (dom != DOMAIN_DESKTOP) {
			if (dom == DOMAIN_MONITOR) {
				fprintf(rsp, "%s\n", m->name);
				continue;
			} else {
				fprintf(rsp, "%s %ux%u%+i%+i %i,%i,%i,%i%s\n", m->name,
				         m->rectangle.width,m->rectangle.height, m->rectangle.x, m->rectangle.y,
				         m->top_padding, m->right_padding, m->bottom_padding, m->left_padding,
				         (m == mon ? " *" : ""));
			}
		}
		query_desktops(m, dom, loc, (dom == DOMAIN_DESKTOP ? 0 : 1), rsp);
	}
}

void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int depth, FILE *rsp)
{
	for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
		if (loc.desktop != NULL && d != loc.desktop)
			continue;
		for (unsigned int i = 0; i < depth; i++)
			fprintf(rsp, "\t");
		if (dom == DOMAIN_DESKTOP) {
			fprintf(rsp, "%s\n", d->name);
			continue;
		} else {
			fprintf(rsp, "%s %u %i %i,%i,%i,%i %c%s\n", d->name, d->border_width,
			        d->window_gap,
			        d->top_padding, d->right_padding, d->bottom_padding, d->left_padding,
			        (d->layout == LAYOUT_TILED ? 'T' : 'M'),
			        (d == m->desk ? " *" : ""));
		}
		query_tree(d, d->root, rsp, depth + 1);
	}
}

void query_tree(desktop_t *d, node_t *n, FILE *rsp, unsigned int depth)
{
	if (n == NULL)
		return;

	for (unsigned int i = 0; i < depth; i++)
		fprintf(rsp, "\t");

	if (is_leaf(n)) {
		client_t *c = n->client;
		fprintf(rsp, "%c %s %s 0x%X %u %ux%u%+i%+i %c%c %c%c %c%c%c%c%s\n",
		         (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')),
		         c->class_name, c->instance_name, c->window, c->border_width,
		         c->floating_rectangle.width, c->floating_rectangle.height,
		         c->floating_rectangle.x, c->floating_rectangle.y,
		         (n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))),
		         (n->split_mode == MODE_AUTOMATIC ? '-' : 'p'),
		         (c->state == STATE_TILED ? '-' : (c->state == STATE_FLOATING ? 'f' : (c->state == STATE_FULLSCREEN ? 'F' : 'p'))),
		         (c->layer == LAYER_NORMAL ? '-' : (c->layer == LAYER_ABOVE ? 'a' : 'b')),
		         (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->private ? 'i' : '-'),
		         (n == d->focus ? " *" : ""));
	} else {
		fprintf(rsp, "%c %c %lf\n", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'),
		        (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), n->split_ratio);
	}

	query_tree(d, n->first_child, rsp, depth + 1);
	query_tree(d, n->second_child, rsp, depth + 1);
}

void query_history(coordinates_t loc, FILE *rsp)
{
	for (history_t *h = history_head; h != NULL; h = h->next) {
		if ((loc.monitor != NULL && h->loc.monitor != loc.monitor)
				|| (loc.desktop != NULL && h->loc.desktop != loc.desktop))
			continue;
		xcb_window_t win = XCB_NONE;
		if (h->loc.node != NULL)
			win = h->loc.node->client->window;
		fprintf(rsp, "%s %s 0x%X\n", h->loc.monitor->name, h->loc.desktop->name, win);
	}
}

void query_stack(FILE *rsp)
{
	for (stacking_list_t *s = stack_head; s != NULL; s = s->next)
		fprintf(rsp, "0x%X\n", s->node->client->window);
}

void query_windows(coordinates_t loc, FILE *rsp)
{
	for (monitor_t *m = mon_head; m != NULL; m = m->next) {
		if (loc.monitor != NULL && m != loc.monitor)
			continue;
		for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
			if (loc.desktop != NULL && d != loc.desktop)
				continue;
			for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
				if (loc.node != NULL && n != loc.node)
					continue;
				fprintf(rsp, "0x%X\n", n->client->window);
			}
		}
	}
}

client_select_t make_client_select(void)
{
	client_select_t sel = {
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE,
		NULL
	};
	return sel;
}

desktop_select_t make_desktop_select(void)
{
	desktop_select_t sel = {
		OPTION_NONE,
		OPTION_NONE,
		OPTION_NONE
	};
	return sel;
}

void cleanup_client_select(client_select_t *sel)
{
	free(sel->layer);
}

bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
{
	client_select_t sel = make_client_select();
	char *tok;
	while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
		tok[0] = '\0';
		tok++;
		if (streq("tiled", tok)) {
			sel.tiled = OPTION_TRUE;
		} else if (streq("!tiled", tok)) {
			sel.tiled = OPTION_FALSE;
		} else if (streq("pseudo_tiled", tok)) {<commit_msg>Use field designators when initializing structures<commit_after>/* Copyright (c) 2012, <NAME>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include "bspwm.h"
#include "desktop.h"
#include "history.h"
#include "messages.h"
#include "monitor.h"
#include "tree.h"
#include "query.h"

void query_monitors(coordinates_t loc, domain_t dom, FILE *rsp)
{
	for (monitor_t *m = mon_head; m != NULL; m = m->next) {
		if (loc.monitor != NULL && m != loc.monitor)
			continue;
		if (dom != DOMAIN_DESKTOP) {
			if (dom == DOMAIN_MONITOR) {
				fprintf(rsp, "%s\n", m->name);
				continue;
			} else {
				fprintf(rsp, "%s %ux%u%+i%+i %i,%i,%i,%i%s\n", m->name,
				         m->rectangle.width,m->rectangle.height, m->rectangle.x, m->rectangle.y,
				         m->top_padding, m->right_padding, m->bottom_padding, m->left_padding,
				         (m == mon ? " *" : ""));
			}
		}
		query_desktops(m, dom, loc, (dom == DOMAIN_DESKTOP ? 0 : 1), rsp);
	}
}

void query_desktops(monitor_t *m, domain_t dom, coordinates_t loc, unsigned int depth, FILE *rsp)
{
	for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
		if (loc.desktop != NULL && d != loc.desktop)
			continue;
		for (unsigned int i = 0; i < depth; i++)
			fprintf(rsp, "\t");
		if (dom == DOMAIN_DESKTOP) {
			fprintf(rsp, "%s\n", d->name);
			continue;
		} else {
			fprintf(rsp, "%s %u %i %i,%i,%i,%i %c%s\n", d->name, d->border_width,
			        d->window_gap,
			        d->top_padding, d->right_padding, d->bottom_padding, d->left_padding,
			        (d->layout == LAYOUT_TILED ? 'T' : 'M'),
			        (d == m->desk ? " *" : ""));
		}
		query_tree(d, d->root, rsp, depth + 1);
	}
}

void query_tree(desktop_t *d, node_t *n, FILE *rsp, unsigned int depth)
{
	if (n == NULL)
		return;

	for (unsigned int i = 0; i < depth; i++)
		fprintf(rsp, "\t");

	if (is_leaf(n)) {
		client_t *c = n->client;
		fprintf(rsp, "%c %s %s 0x%X %u %ux%u%+i%+i %c%c %c%c %c%c%c%c%s\n",
		         (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')),
		         c->class_name, c->instance_name, c->window, c->border_width,
		         c->floating_rectangle.width, c->floating_rectangle.height,
		         c->floating_rectangle.x, c->floating_rectangle.y,
		         (n->split_dir == DIR_UP ? 'U' : (n->split_dir == DIR_RIGHT ? 'R' : (n->split_dir == DIR_DOWN ? 'D' : 'L'))),
		         (n->split_mode == MODE_AUTOMATIC ? '-' : 'p'),
		         (c->state == STATE_TILED ? '-' : (c->state == STATE_FLOATING ? 'f' : (c->state == STATE_FULLSCREEN ? 'F' : 'p'))),
		         (c->layer == LAYER_NORMAL ? '-' : (c->layer == LAYER_ABOVE ? 'a' : 'b')),
		         (c->urgent ? 'u' : '-'), (c->locked ? 'l' : '-'), (c->sticky ? 's' : '-'), (c->private ? 'i' : '-'),
		         (n == d->focus ? " *" : ""));
	} else {
		fprintf(rsp, "%c %c %lf\n", (n->split_type == TYPE_HORIZONTAL ? 'H' : 'V'),
		        (n->birth_rotation == 90 ? 'a' : (n->birth_rotation == 270 ? 'c' : 'm')), n->split_ratio);
	}

	query_tree(d, n->first_child, rsp, depth + 1);
	query_tree(d, n->second_child, rsp, depth + 1);
}

void query_history(coordinates_t loc, FILE *rsp)
{
	for (history_t *h = history_head; h != NULL; h = h->next) {
		if ((loc.monitor != NULL && h->loc.monitor != loc.monitor)
				|| (loc.desktop != NULL && h->loc.desktop != loc.desktop))
			continue;
		xcb_window_t win = XCB_NONE;
		if (h->loc.node != NULL)
			win = h->loc.node->client->window;
		fprintf(rsp, "%s %s 0x%X\n", h->loc.monitor->name, h->loc.desktop->name, win);
	}
}

void query_stack(FILE *rsp)
{
	for (stacking_list_t *s = stack_head; s != NULL; s = s->next)
		fprintf(rsp, "0x%X\n", s->node->client->window);
}

void query_windows(coordinates_t loc, FILE *rsp)
{
	for (monitor_t *m = mon_head; m != NULL; m = m->next) {
		if (loc.monitor != NULL && m != loc.monitor)
			continue;
		for (desktop_t *d = m->desk_head; d != NULL; d = d->next) {
			if (loc.desktop != NULL && d != loc.desktop)
				continue;
			for (node_t *n = first_extrema(d->root); n != NULL; n = next_leaf(n, d->root)) {
				if (loc.node != NULL && n != loc.node)
					continue;
				fprintf(rsp, "0x%X\n", n->client->window);
			}
		}
	}
}

client_select_t make_client_select(void)
{
	client_select_t sel = {
		.tiled = OPTION_NONE,
		.pseudo_tiled = OPTION_NONE,
		.floating = OPTION_NONE,
		.fullscreen = OPTION_NONE,
		.locked = OPTION_NONE,
		.sticky = OPTION_NONE,
		.private = OPTION_NONE,
		.urgent = OPTION_NONE,
		.same_class = OPTION_NONE,
		.automatic = OPTION_NONE,
		.local = OPTION_NONE,
		.focused = OPTION_NONE,
		.layer = NULL
	};
	return sel;
}

desktop_select_t make_desktop_select(void)
{
	desktop_select_t sel = {
		.occupied = OPTION_NONE,
		.urgent = OPTION_NONE,
		.local = OPTION_NONE
	};
	return sel;
}

void cleanup_client_select(client_select_t *sel)
{
	free(sel->layer);
}

bool node_from_desc(char *desc, coordinates_t *ref, coordinates_t *dst)
{
	client_select_t sel = make_client_select();
	char *tok;
	while ((tok = strrchr(desc, CAT_CHR)) != NULL) {
		tok[0] = '\0';
		tok++;
		if (streq("tiled", tok)) {
			sel.tiled = OPTION_TRUE;
		} else if (streq("!tiled", tok)) {
			sel.tiled = OPTION_FALSE;
		} else if (streq("pseudo_tiled", tok)) {
{'fraction_non_alphanumeric': 0.17147760961148384, 'fraction_numerical': 0.004524886877828055, 'mean_word_length': 3.360204081632653, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 169, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6750898', 'n_tokens_mistral': 5241, 'n_tokens_neox': 4787, 'n_words': 1273}