summaryrefslogtreecommitdiff
path: root/src/utils.h
blob: 942b3ebb940997444f3ab44da5e4130a053a050f (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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/** Copyright 2011-2013 Thorsten Wißmann. All rights reserved.
 *
 * This software is licensed under the "Simplified BSD License".
 * See LICENSE for details */

#ifndef __HERBST_UTILS_H_
#define __HERBST_UTILS_H_

#include "glib-backports.h"
#include <stddef.h>
#include <stdbool.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include "x11-types.h"
#include <array>

#define LENGTH(X) (sizeof(X)/sizeof(*X))
#define SHIFT(ARGC, ARGV) (--(ARGC) && ++(ARGV))
#define MOD(X, N) ((((X) % (signed)(N)) + (signed)(N)) % (signed)(N))

#define container_of(ptr, type, member) \
    ((type *)( (char *)(ptr)- offsetof(type,member) ))

// control structures
#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define SWAP(TYPE,a,b) do { \
            TYPE TMPNAME = (a); \
            (a) = (b); \
            (b) = TMPNAME; \
        } while(0);

/// print a printf-like message to stderr and exit
void die(const char *errstr, ...);

// get X11 color from color string
HSColor getcolor(const char *colstr);
bool getcolor_error(const char *colstr, HSColor* color);

#define ATOM(A) XInternAtom(g_display, (A), False)

GString* window_property_to_g_string(Display* dpy, Window window, Atom atom);
GString* window_class_to_g_string(Display* dpy, Window window);
GString* window_instance_to_g_string(Display* dpy, Window window);
int window_pid(Display* dpy, Window window);

typedef void* HSTree;
struct HSTreeInterface;
typedef struct HSTreeInterface {
    struct HSTreeInterface  (*nth_child)(HSTree root, size_t idx);
    size_t                  (*child_count)(HSTree root);
    void                    (*append_caption)(HSTree root, GString* output);
    HSTree                  data;
    void                    (*destructor)(HSTree data); /* how to free the data tree */
} HSTreeInterface;

void tree_print_to(HSTreeInterface* intface, GString* output);


bool is_herbstluft_window(Display* dpy, Window window);

bool is_window_mapable(Display* dpy, Window window);
bool is_window_mapped(Display* dpy, Window window);

bool window_has_property(Display* dpy, Window window, char* prop_name);

bool string_to_bool_error(const char* string, bool oldvalue, bool* error);
bool string_to_bool(const char* string, bool oldvalue);

const char* strlasttoken(const char* str, const char* delim);

time_t get_monotonic_timestamp();

// duplicates an argument-vector
char** argv_duplicate(int argc, char** argv);
// frees all entries in argument-vector and then the vector itself
void argv_free(int argc, char** argv);

Rectangle parse_rectangle(char* string);

void g_queue_remove_element(GQueue* queue, GList* elem);

// find an element in an array buf with elems elements of size size.
int array_find(const void* buf, size_t elems, size_t size, const void* needle);
void array_reverse(void* void_buf, size_t elems, size_t size);

template<class T, int S> struct ArrayInitializer {
    ArrayInitializer(std::initializer_list<std::pair<int,T> > il) {
	for (auto i = il.begin(); i != il.end(); i++) {
	    a[i->first] = i->second;
	}
    }

    std::array<T, S> a;
};

int min(int a, int b);

// utils for tables
typedef bool (*MemberEquals)(void* pmember, const void* needle);
bool memberequals_string(void* pmember, const void* needle);
bool memberequals_int(void* pmember, const void* needle);

void* table_find(void* start, size_t elem_size, size_t count,
                 size_t member_offset, MemberEquals equals, const void* needle);

void set_window_double_border(Display *dpy, Window win, int ibw,
                              unsigned long inner_color, unsigned long outer_color);

#define STATIC_TABLE_FIND(TYPE, TABLE, MEMBER, EQUALS, NEEDLE)  \
    ((TYPE*) table_find((TABLE),                                \
                        sizeof(TABLE[0]),                       \
                        LENGTH((TABLE)),                        \
                        offsetof(TYPE, MEMBER),                 \
                        EQUALS,                                 \
                        (NEEDLE)))

#define STATIC_TABLE_FIND_STR(TYPE, TABLE, MEMBER, NEEDLE)  \
    STATIC_TABLE_FIND(TYPE, TABLE, MEMBER, memberequals_string, NEEDLE)

#define INDEX_OF(ARRAY, PELEM) \
    (((char*)(PELEM) - (char*)(ARRAY)) / (sizeof (*ARRAY)))

// returns the unichar in GSTR at position GSTR
#define UTF8_STRING_AT(GSTR, OFFS) \
    g_utf8_get_char( \
        g_utf8_offset_to_pointer((GSTR), (OFFS))) \

#define RECTANGLE_EQUALS(a, b) (\
        (a).x == (b).x &&   \
        (a).y == (b).y &&   \
        (a).width == (b).width &&   \
        (a).height == (b).height    \
    )

// returns an posix sh escaped string or NULL if there is nothing to escape
// if a new string is returned, then the caller has to free it
char* posix_sh_escape(const char* source);
// does the reverse action to posix_sh_escape by modifing the string
void posix_sh_compress_inplace(char* str);

#endif