vtetypes.hh 8.97 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright © 2015 Christian Persch
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

20
#include <pango/pango.h>
21
#include <gdk/gdk.h>
22
#include <errno.h>
23

24
#include <cstdint>
25
#include <memory>
26

27 28 29 30 31 32
#ifdef VTE_DEBUG
#define IFDEF_DEBUG(str) str
#else
#define IFDEF_DEBUG(str)
#endif

33
namespace vte {
34

35 36 37 38
namespace grid {

        typedef long row_t;
        typedef long column_t;
39
        typedef int half_t;
40

41
        struct coords : public std::pair<row_t, column_t> {
42
        public:
43 44
                using base_type = std::pair<row_t, column_t>;

45
                coords() = default;
46
                coords(row_t r, column_t c) : base_type{r, c} { }
47

48 49
                inline void set_row(row_t r)       { first = r;  }
                inline void set_column(column_t c) { second = c; }
50

51 52
                inline row_t row()       const { return first;  }
                inline column_t column() const { return second; }
53

54 55
                IFDEF_DEBUG(char const* to_string() const);
        };
56

57 58 59
        struct halfcolumn_t : public std::pair<column_t, half_t> {
        public:
                using base_type = std::pair<column_t, half_t>;
60

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
                halfcolumn_t() = default;
                halfcolumn_t(column_t c, half_t h) : base_type{c, h} { }

                inline void set_column(column_t c) { first = c;  }
                inline void set_half(half_t h)     { second = h; }

                inline column_t column() const { return first;  }
                inline half_t half()     const { return second; }
        };

        struct halfcoords : public std::pair<row_t, halfcolumn_t> {
        public:
                using base_type = std::pair<row_t, halfcolumn_t>;

                halfcoords() = default;
                halfcoords(row_t r, halfcolumn_t hc) : base_type{r, hc} { }
                halfcoords(row_t r, column_t c, half_t h) : base_type{r, halfcolumn_t(c, h)} { }
78

79 80 81 82 83 84 85
                inline void set_row(row_t r)                { first = r;   }
                inline void set_halfcolumn(halfcolumn_t hc) { second = hc; }

                inline row_t row()               const { return first;  }
                inline halfcolumn_t halfcolumn() const { return second; }

                IFDEF_DEBUG(char const* to_string() const);
86 87
        };

88
        /* end is exclusive (or: start and end point to boundaries between cells) */
89 90 91 92 93 94
        struct span {
        public:
                span() = default;
                span(coords const& s, coords const& e) : m_start(s), m_end(e) { }
                span(row_t sr, column_t sc, row_t er, column_t ec) : m_start(sr, sc), m_end(er, ec) { }

95
                inline void set(coords const&s, coords const& e) { m_start = s; m_end = e; }
96 97 98 99 100 101 102 103 104 105
                inline void set_start(coords const& s) { m_start = s; }
                inline void set_end(coords const& e) { m_end = e; }

                inline bool operator == (span const& rhs) const { return m_start == rhs.m_start && m_end == rhs.m_end; }
                inline bool operator != (span const& rhs) const { return m_start != rhs.m_start || m_end != rhs.m_end; }

                inline coords const& start() const { return m_start; }
                inline coords const& end()   const { return m_end; }
                inline row_t start_row()       const { return m_start.row(); }
                inline row_t end_row()         const { return m_end.row(); }
106 107
                /* Get the last row that actually contains characters belonging to this span. */
                inline row_t last_row()        const { return m_end.column() > 0 ? m_end.row() : m_end.row() - 1; }
108 109 110
                inline column_t start_column() const { return m_start.column(); }
                inline column_t end_column()   const { return m_end.column(); }

111 112
                inline void clear() { m_start = coords(-1, -1); m_end = coords(-1, -1); }
                inline bool empty() const { return m_start >= m_end; }
113 114
                inline explicit operator bool() const { return !empty(); }

115
                inline bool contains(coords const& p) const { return m_start <= p && p < m_end; }
116
                // FIXME make "block" a member of the span? Or subclasses for regular and block spans?
117
                inline bool box_contains(coords const& p) const { return m_start.row() <= p.row() && p.row() <= m_end.row() &&
118
                                                                         m_start.column() <= p.column() && p.column() < m_end.column(); }
119

120 121
                inline bool contains(row_t row, column_t column) { return contains(coords(row, column)); }

122
                IFDEF_DEBUG(char const* to_string() const);
123

124 125 126 127 128 129
        private:
                coords m_start;
                coords m_end;
        };

} /* namespace grid */
130

Christian Persch's avatar
Christian Persch committed
131 132 133 134 135
namespace view {

        /* FIXMEchpe: actually 32-bit int would be sufficient here */
        typedef long coord_t;

136
        class coords {
Christian Persch's avatar
Christian Persch committed
137 138 139 140 141 142 143 144
        public:
                coords() = default;
                coords(coord_t x_, coord_t y_) : x(x_), y(y_) { }

                inline bool operator == (coords const& rhs) const { return x == rhs.x && y == rhs.y; }
                inline bool operator != (coords const& rhs) const { return x != rhs.x || y != rhs.y; }

                void swap(coords &rhs) { coords tmp = rhs; rhs = *this; *this = tmp; }
145

146
                IFDEF_DEBUG(char const* to_string() const);
147

Christian Persch's avatar
Christian Persch committed
148 149 150
        public:
                coord_t x;
                coord_t y;
151
        };
Christian Persch's avatar
Christian Persch committed
152

153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
        class extents {
        public:
                extents() = default;
                extents(coord_t w, coord_t h) : m_width(w), m_height(h) { }

                inline coord_t width() const { return m_width; }
                inline coord_t height() const { return m_height; }

                inline bool operator == (extents const& rhs) const { return m_width == rhs.m_width && m_height == rhs.m_height; }
                inline bool operator != (extents const& rhs) const { return m_width != rhs.m_width || m_height != rhs.m_height; }

                IFDEF_DEBUG(char const* to_string() const);

        private:
                coord_t m_width;
                coord_t m_height;
        };

Christian Persch's avatar
Christian Persch committed
171 172
} /* namespace view */

173 174 175 176 177 178 179 180 181 182
namespace color {

        /* 24-bit (8 bit per channel) packed colour */
        /* FIXME: we could actually support 10 bit per channel */
        typedef guint32 packed;

        class rgb : public PangoColor {
        public:
                rgb() = default;
                rgb(PangoColor const& c) { *static_cast<PangoColor*>(this) = c; }
183
                rgb(GdkRGBA const* c);
184
                rgb(GdkRGBA const& c) : rgb(&c) { }
185 186
                rgb(uint16_t r, uint16_t g, uint16_t b)
                        : PangoColor{r, g, b} { }
187 188

                bool parse(char const* spec);
189 190

                void from_pango(PangoColor const& c) { *static_cast<PangoColor*>(this) = c; }
191 192 193 194

                inline bool operator == (rgb const& rhs) const {
                        return red == rhs.red && green == rhs.green && blue == rhs.blue;
                }
195

196
                IFDEF_DEBUG(char const* to_string() const);
197 198 199 200
        };

} /* namespace color */

201 202 203 204 205 206 207 208 209 210 211
namespace util {

        class restore_errno {
        public:
                restore_errno() { m_errsv = errno; }
                ~restore_errno() { errno = m_errsv; }
                operator int () const { return m_errsv; }
        private:
                int m_errsv;
        };

212 213 214 215 216 217 218
        class smart_fd {
        public:
                smart_fd() : m_fd(-1) { }
                explicit smart_fd(int fd) : m_fd(fd) { }
                ~smart_fd() { if (m_fd != -1) { restore_errno errsv; close(m_fd); } }

                inline smart_fd& operator = (int rhs) { if (m_fd != -1) { restore_errno errsv; close(m_fd); } m_fd = rhs; return *this; }
Christian Persch's avatar
Christian Persch committed
219
                inline smart_fd& operator = (smart_fd& rhs) { if (&rhs != this) { if (m_fd != -1) { restore_errno errsv; close(m_fd); } m_fd = rhs.m_fd; rhs.m_fd = -1; } return *this; }
220 221 222 223 224 225 226
                inline operator int () const { return m_fd; }
                inline operator int* () { g_assert(m_fd == -1); return &m_fd; }

                int steal() { auto d = m_fd; m_fd = -1; return d; }

                /* Prevent accidents */
                smart_fd(smart_fd const&) = delete;
Christian Persch's avatar
Christian Persch committed
227
                smart_fd(smart_fd&&) = delete;
228
                smart_fd& operator = (smart_fd const&) = delete;
Christian Persch's avatar
Christian Persch committed
229
                smart_fd& operator = (smart_fd&&) = delete;
230 231 232 233 234

        private:
                int m_fd;
        };

235 236
} /* namespace util */

237
} /* namespace vte */