<commit_before>/*
 * (C)opyright MMIV-MMVI <NAME> <<EMAIL>>
 * See LICENSE file for license details.
 */

#include <stdlib.h>
#include <string.h>

#include "wm.h"

static Vector *
vector_of_areas(AreaVector *av)
{
	return (Vector *) av;
}

Area *
create_area(View *v)
{
	if(v->area.size >= 2 && v->area.size - 1 >= rect.width / MIN_COLWIDTH)
		return nil;
	{
		static unsigned short id = 1;
		Area *a = cext_emallocz(sizeof(Area));
		a->view = v;
		a->id = id++;
		a->rect = rect;
		a->rect.height = rect.height - brect.height;
		if(v->area.size > 1)
			a->rect.width = rect.width / (v->area.size - 1);
		cext_vattach(vector_of_areas(&v->area), a);
		v->sel = v->area.size - 1;
		return a;
	}
}

void
destroy_area(Area *a)
{
	unsigned int i;
	View *v = a->view;
	if(a->frame.size)
		return;
	if(a->frame.data)
		free(a->frame.data);
	if(v->revert == idx_of_area(a))
		v->revert = 0;
	for(i = 0; i < client.size; i++)
		if(client.data[i]->revert == a)
			client.data[i]->revert = 0;
	cext_vdetach(vector_of_areas(&v->area), a);
	if(v->sel > 1)
		v->sel--;
	free(a);
}

int
idx_of_area(Area *a)
{
	int i;
	View *v = a->view;
	for(i = 0; i < v->area.size; i++)
		if(v->area.data[i] == a)
			return i;
	return -1;
}

int
idx_of_area_id(View *v, unsigned short id)
{
	int i;
	for(i = 0; i < v->area.size; i++)
		if(v->area.data[i]->id == id)
			return i;
	return -1;
}

void
select_area(Area *a, char *arg)
{
	Area *new;
	View *v = a->view;
	int i = idx_of_area(a);

	if(i == -1)
		return;
	if(i)
		v->revert = i;

	if(!strncmp(arg, "toggle", 7)) {
		if(i)
			i = 0;
		else if(v->revert > 0 && v->revert < v->area.size)
			i = v->revert;
		else
			i = 1;
	} else if(!strncmp(arg, "prev", 5)) {
		if(i > 0) {
			if(i == 1)
				i = v->area.size - 1;
			else
				i--;
		}
	} else if(!strncmp(arg, "next", 5)) {
		if(i > 0) {
			if(i + 1 < v->area.size)
				i++;
			else
				i = 1;
		}
	}
	else {
		const char *errstr;
		i = cext_strtonum(arg, 0, v->area.size - 1, &errstr);
		if(errstr)
			return;
	}
	new = v->area.data[i];
	if(new->frame.size)
		focus_client(new->frame.data[new->sel]->client);
	v->sel = i;
	for(i = 0; i < a->frame.size; i++)
		draw_client(a->frame.data[i]->client);
}

void
send_to_area(Area *to, Area *from, Client *c)
{
	c->revert = from;
	detach_from_area(from, c);
	attach_to_area(to, c);
	focus_client(c);
}

void
place_client(Area *a, Client *c)
{
	static unsigned int mx, my;
	static Bool *field = nil;
	Bool fit = False;
	unsigned int i, j, k, x, y, maxx, maxy, dx, dy, cx, cy;
	XPoint p1 = {0, 0}, p2 = {0, 0};
	Frame *f = c->frame.data[c->sel];

	if(c->trans || f->rect.width >= a->rect.width
			|| f->rect.height >= a->rect.height)
		return;

	if(!field) {
		mx = rect.width / 8;
		my = rect.height / 8;
		field = cext_emallocz(my * mx * sizeof(Bool));
	}

	for(y = 0; y < my; y++)
		for(x = 0; x < mx; x++)
			field[y*mx + x] = True;

	dx = rect.width / mx;
	dy = rect.height / my;
	for(k = 0; k < a->frame.size; k++) {
		Frame *fr = a->frame.data[k];
		if(fr == f) {
			cx = f->rect.width / dx;
			cy = f->rect.height / dy;
			continue;
		}
		x = fr->rect.x / dx;
		y = fr->rect.y / dy;
		maxx = x + fr->rect.width / dx;
		maxy = y + fr->rect.height / dy;
		for(j = y; j < maxy; j++)
			for(i = x; i < maxx; i++)
				field[j*mx + i] = False;
	}

	for(y = 0; y < my; y++)
		for(x = 0; x < mx; x++) {
			if(field[y*mx + x]) {
				for(i = x; (i < mx) && field[y*mx + i]; i++);
				for(j = y; (j < my) && field[j*mx + x]; j++);
				if(((i - x) * (j - y) > (p2.x - p1.x) * (p2.y - p1.y)) 
					&& (i - x > cx) && (j - y > cy))
				{
					fit = True;
					p1.x = x;
					p1.y = y;
					p2.x = i;
					p2.y = j;
					fprintf(stderr, "place_client fit %d %d %d %d, (%d > %d) && (%d > %d)\n",
						   	x, y, i, j, i-x, cx, j - y, cy);
				}
			}
		}
<commit_msg>made place_client more robust against clients with obfuscated sizes<commit_after>/*
 * (C)opyright MMIV-MMVI <NAME> <<EMAIL>>
 * See LICENSE file for license details.
 */

#include <stdlib.h>
#include <string.h>

#include "wm.h"

static Vector *
vector_of_areas(AreaVector *av)
{
	return (Vector *) av;
}

Area *
create_area(View *v)
{
	if(v->area.size >= 2 && v->area.size - 1 >= rect.width / MIN_COLWIDTH)
		return nil;
	{
		static unsigned short id = 1;
		Area *a = cext_emallocz(sizeof(Area));
		a->view = v;
		a->id = id++;
		a->rect = rect;
		a->rect.height = rect.height - brect.height;
		if(v->area.size > 1)
			a->rect.width = rect.width / (v->area.size - 1);
		cext_vattach(vector_of_areas(&v->area), a);
		v->sel = v->area.size - 1;
		return a;
	}
}

void
destroy_area(Area *a)
{
	unsigned int i;
	View *v = a->view;
	if(a->frame.size)
		return;
	if(a->frame.data)
		free(a->frame.data);
	if(v->revert == idx_of_area(a))
		v->revert = 0;
	for(i = 0; i < client.size; i++)
		if(client.data[i]->revert == a)
			client.data[i]->revert = 0;
	cext_vdetach(vector_of_areas(&v->area), a);
	if(v->sel > 1)
		v->sel--;
	free(a);
}

int
idx_of_area(Area *a)
{
	int i;
	View *v = a->view;
	for(i = 0; i < v->area.size; i++)
		if(v->area.data[i] == a)
			return i;
	return -1;
}

int
idx_of_area_id(View *v, unsigned short id)
{
	int i;
	for(i = 0; i < v->area.size; i++)
		if(v->area.data[i]->id == id)
			return i;
	return -1;
}

void
select_area(Area *a, char *arg)
{
	Area *new;
	View *v = a->view;
	int i = idx_of_area(a);

	if(i == -1)
		return;
	if(i)
		v->revert = i;

	if(!strncmp(arg, "toggle", 7)) {
		if(i)
			i = 0;
		else if(v->revert > 0 && v->revert < v->area.size)
			i = v->revert;
		else
			i = 1;
	} else if(!strncmp(arg, "prev", 5)) {
		if(i > 0) {
			if(i == 1)
				i = v->area.size - 1;
			else
				i--;
		}
	} else if(!strncmp(arg, "next", 5)) {
		if(i > 0) {
			if(i + 1 < v->area.size)
				i++;
			else
				i = 1;
		}
	}
	else {
		const char *errstr;
		i = cext_strtonum(arg, 0, v->area.size - 1, &errstr);
		if(errstr)
			return;
	}
	new = v->area.data[i];
	if(new->frame.size)
		focus_client(new->frame.data[new->sel]->client);
	v->sel = i;
	for(i = 0; i < a->frame.size; i++)
		draw_client(a->frame.data[i]->client);
}

void
send_to_area(Area *to, Area *from, Client *c)
{
	c->revert = from;
	detach_from_area(from, c);
	attach_to_area(to, c);
	focus_client(c);
}

void
place_client(Area *a, Client *c)
{
	static unsigned int mx, my;
	static Bool *field = nil;
	Bool fit = False;
	unsigned int i, j, k, x, y, maxx, maxy, dx, dy, cx, cy;
	XPoint p1 = {0, 0}, p2 = {0, 0};
	Frame *f = c->frame.data[c->sel];

	if(c->trans || f->rect.width >= a->rect.width
			|| f->rect.height >= a->rect.height)
		return;

	if(!field) {
		mx = rect.width / 8;
		my = rect.height / 8;
		field = cext_emallocz(my * mx * sizeof(Bool));
	}

	for(y = 0; y < my; y++)
		for(x = 0; x < mx; x++)
			field[y*mx + x] = True;

	dx = rect.width / mx;
	dy = rect.height / my;
	for(k = 0; k < a->frame.size; k++) {
		Frame *fr = a->frame.data[k];
		if(fr == f) {
			cx = f->rect.width / dx;
			cy = f->rect.height / dy;
			continue;
		}
		x = fr->rect.x / dx;
		y = fr->rect.y / dy;
		maxx = x + fr->rect.width / dx;
		maxy = y + fr->rect.height / dy;
		for(j = y; j < my && j < maxy; j++)
			for(i = x; i < mx && i < maxx; i++)
				field[j*mx + i] = False;
	}

	for(y = 0; y < my; y++)
		for(x = 0; x < mx; x++) {
			if(field[y*mx + x]) {
				for(i = x; (i < mx) && field[y*mx + i]; i++);
				for(j = y; (j < my) && field[j*mx + x]; j++);
				if(((i - x) * (j - y) > (p2.x - p1.x) * (p2.y - p1.y)) 
					&& (i - x > cx) && (j - y > cy))
				{
					fit = True;
					p1.x = x;
					p1.y = y;
					p2.x = i;
					p2.y = j;
					fprintf(stderr, "place_client fit %d %d %d %d, (%d > %d) && (%d > %d)\n",
						   	x, y, i, j, i-x, cx, j - y, cy);
				}
			}
		}

{'fraction_non_alphanumeric': 0.22452187581870578, 'fraction_numerical': 0.013361278490961487, 'mean_word_length': 2.484710178000913, 'pattern_counts': {'":': 0, '<': 45, '<?xml version=': 0, '>': 167, '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': '5122909', 'n_tokens_mistral': 3972, 'n_tokens_neox': 3592, 'n_words': 860}