initial commit
This commit is contained in:
commit
1c606d0274
36 changed files with 9908 additions and 0 deletions
184
layout.c
Normal file
184
layout.c
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
/*
|
||||
* Copyright (c) 2024, Richard Acayan. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "graphics.h"
|
||||
#include "layout.h"
|
||||
#include "parser.h"
|
||||
#include "ufkbd.h"
|
||||
|
||||
static struct ufkbd_layout_row *search_row(struct ufkbd_layout *layout, int y)
|
||||
{
|
||||
struct ufkbd_layout_row *row;
|
||||
size_t row1 = 0, row2;
|
||||
size_t idx;
|
||||
|
||||
if (layout->rows == NULL)
|
||||
return NULL;
|
||||
|
||||
row2 = layout->n_rows - 1;
|
||||
|
||||
do {
|
||||
idx = (row1 + row2) / 2;
|
||||
row = &layout->rows[idx];
|
||||
|
||||
if (row->y1 <= y)
|
||||
row1 = idx;
|
||||
|
||||
if (row->y2 >= y)
|
||||
row2 = idx;
|
||||
} while (row2 - row1 > 1);
|
||||
|
||||
if (layout->rows[row1].y1 <= y && layout->rows[row1].y2 >= y)
|
||||
return &layout->rows[row1];
|
||||
else if (layout->rows[row2].y1 <= y && layout->rows[row2].y2 >= y)
|
||||
return &layout->rows[row2];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct ufkbd_layout_column *search_col(struct ufkbd_layout_row *row, int x)
|
||||
{
|
||||
struct ufkbd_layout_column *col;
|
||||
size_t col1 = 0, col2;
|
||||
size_t idx;
|
||||
|
||||
col2 = row->n_cols - 1;
|
||||
|
||||
do {
|
||||
idx = (col1 + col2) / 2;
|
||||
col = &row->cols[idx];
|
||||
|
||||
if (col->x1 <= x)
|
||||
col1 = idx;
|
||||
|
||||
if (col->x2 >= x)
|
||||
col2 = idx;
|
||||
} while (col2 - col1 > 1);
|
||||
|
||||
if (row->cols[col1].x1 <= x && row->cols[col1].x2 >= x)
|
||||
return &row->cols[col1];
|
||||
else if (row->cols[col2].x1 <= x && row->cols[col2].x2 >= x)
|
||||
return &row->cols[col2];
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct ufkbd_key *ufkbd_layout_search(struct ufkbd_layout *layout, int x, int y,
|
||||
int *x1, int *y1, int *x2, int *y2)
|
||||
{
|
||||
struct ufkbd_layout_row *row;
|
||||
struct ufkbd_layout_column *col;
|
||||
|
||||
if (layout == NULL)
|
||||
return NULL;
|
||||
|
||||
row = search_row(layout, y);
|
||||
if (row == NULL)
|
||||
return NULL;
|
||||
|
||||
col = search_col(row, x);
|
||||
if (col == NULL)
|
||||
return NULL;
|
||||
|
||||
if (x1 != NULL)
|
||||
*x1 = col->x1;
|
||||
|
||||
if (y1 != NULL)
|
||||
*y1 = row->y1;
|
||||
|
||||
if (x2 != NULL)
|
||||
*x2 = col->x2;
|
||||
|
||||
if (y2 != NULL)
|
||||
*y2 = row->y2;
|
||||
|
||||
return col->key;
|
||||
}
|
||||
|
||||
void ufkbd_layout_foreach(struct ufkbd_layout *layout,
|
||||
void (*func)(struct ufkbd_key *key,
|
||||
int x1, int y1, int x2, int y2,
|
||||
void *data),
|
||||
void *data)
|
||||
{
|
||||
struct ufkbd_layout_row *row;
|
||||
struct ufkbd_layout_column *col;
|
||||
size_t y, x;
|
||||
|
||||
for (y = 0; y < layout->n_rows; y++) {
|
||||
row = &layout->rows[y];
|
||||
|
||||
for (x = 0; x < row->n_cols; x++) {
|
||||
col = &row->cols[x];
|
||||
func(col->key,
|
||||
col->x1, row->y1, col->x2, row->y2,
|
||||
data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ufkbd_layout_resize(struct ufkbd_layout *layout, int width, int height)
|
||||
{
|
||||
struct ufkbd_layout_row *row;
|
||||
struct ufkbd_layout_column *col;
|
||||
size_t y, x;
|
||||
|
||||
for (y = 0; y < layout->n_rows; y++) {
|
||||
row = &layout->rows[y];
|
||||
|
||||
row->y1 = row->y1_unscaled * height / layout->n_rows;
|
||||
row->y2 = row->y2_unscaled * height / layout->n_rows - 1;
|
||||
|
||||
if (row->y2 < row->y1)
|
||||
row->y2 = row->y1;
|
||||
|
||||
for (x = 0; x < row->n_cols; x++) {
|
||||
col = &row->cols[x];
|
||||
col->x1 = col->x1_unscaled * width / layout->max_cols;
|
||||
col->x2 = col->x2_unscaled * width / layout->max_cols - 1;
|
||||
|
||||
if (col->x2 < col->x1)
|
||||
col->x2 = col->x1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ufkbd_layout *ufkbd_layout_init(void)
|
||||
{
|
||||
struct ufkbd_layout *layout;
|
||||
|
||||
layout = malloc(sizeof(*layout));
|
||||
if (layout == NULL)
|
||||
return NULL;
|
||||
|
||||
layout->max_cols = 0;
|
||||
layout->n_rows = 0;
|
||||
layout->rows = NULL;
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
void ufkbd_layout_uninit(struct ufkbd_layout *layout)
|
||||
{
|
||||
struct ufkbd_layout_row *row;
|
||||
size_t x, y;
|
||||
|
||||
for (y = 0; y < layout->n_rows; y++) {
|
||||
row = &layout->rows[y];
|
||||
|
||||
for (x = 0; x < row->n_cols; x++)
|
||||
free(row->cols[x].key);
|
||||
|
||||
free(row->cols);
|
||||
}
|
||||
|
||||
free(layout->rows);
|
||||
free(layout);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue