aboutsummaryrefslogtreecommitdiff
path: root/src/util.h
blob: 78dcad79a3def0c3cf68fcdb49ebfff1773c06bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#ifndef COMET_UTIL_H
#define COMET_UTIL_H

#include <time.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <cairo.h>

#define unreachable() log_panic("The impossible happened");

// Color representation normalized to [0, 1]
//
typedef struct {
    double r, g, b, a;
} color_t;

typedef struct {
    color_t *colors;
    size_t length;
    cairo_pattern_t *cached;
} gradient_t;

static inline color_t color_rgba(int r, int g, int b, int a)
{
    color_t color = { r / 255.0, g / 255.0, b / 255.0, a / 255.0 };
    return color;
}

static inline color_t color_rgb(int r, int g, int b)
{
    return color_rgba(r, g, b, 255);
}

static inline color_t color_hex(unsigned int h)
{
    return color_rgb((h >> 16) & 0xff, (h >>  8) & 0xff, h & 0xff);
}

char *color_to_string(color_t *color);

void color_print(FILE *stream, color_t *color);

char *gradient_to_string(gradient_t *gradient);

void gradient_free(gradient_t *gradient);

const struct timespec timespec_from_ms(long ms);

const long timespec_to_ms(struct timespec ts);

struct timespec timespec_diff(struct timespec a, struct timespec b);

struct timespec timespec_add(struct timespec a, struct timespec b);

struct timespec timespec_div(struct timespec ts, int n);

bool timespec_greater(struct timespec a, struct timespec b);

bool timespec_zero(struct timespec ts);

void timespec_print(FILE *stream, struct timespec *ts);

// Check if point (px, py) is inside a rectangle in (x, y), (x+w, y), (x, y+h) and (w+h, y+h)
bool check_rect(int px, int py, int x, int y, int w, int h);

// Check if point (px, py) is inside a circle of radius r and center (x, y)
bool check_circle(int px, int py, int x, int y, int r);

// Check if point (px, py) is inside a capsule in (x, y), (x+w, y), (x, y+h) and (w+h, y+h)
bool check_capsule(int px, int py, int x, int y, int w, int h);

char *strslice(const char *string, size_t start, size_t end);

char *strcopy(const char *string);

bool strfind(const char *string, const char *cases[]);

size_t strprefix(const char *string, const char *prefix);

void strfree(char **list);

bool iszero(const void *ptr, size_t size);

typedef enum {
    UNIT_B   = 1 << 0,
    UNIT_KB  = 1 << 1,
    UNIT_MB  = 1 << 2,
    UNIT_GB  = 1 << 3,
    UNIT_TB  = 1 << 4,
    UNIT_SI = 1 << 5,
    UNIT_MASK = UNIT_B | UNIT_KB | UNIT_MB | UNIT_GB | UNIT_TB | UNIT_SI,
} unit_t;

int snprintf_units(char *buffer, size_t max, uint64_t bytes, unit_t unit);

#endif