1 /*
2 * Copyright © 2015 David Herrmann <dh.herrmann@gmail.com>
3 * Copyright © 2018 Christian Persch
4 *
5 * This library is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published
7 * by the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library. If not, see <https://www.gnu.org/licenses/>.
17 */
18
19 #pragma once
20
21 #include <assert.h>
22
23 /*
24 * vte_seq_arg_t:
25 *
26 * A type to hold a CSI, OSC or DCS parameter.
27 *
28 * Parameters can be final or nonfinal.
29 *
30 * Final parameters are those that occur at the end of the
31 * parameter list, or the end of a subparameter list.
32 *
33 * Nonfinal parameters are those that have subparameters
34 * after them.
35 *
36 * Parameters have default value or have a nondefault value.
37 */
38 typedef int vte_seq_arg_t;
39
40 #define VTE_SEQ_ARG_FLAG_VALUE (1 << 16)
41 #define VTE_SEQ_ARG_FLAG_NONFINAL (1 << 17)
42 #define VTE_SEQ_ARG_FLAG_MASK (VTE_SEQ_ARG_FLAG_VALUE | VTE_SEQ_ARG_FLAG_NONFINAL)
43 #define VTE_SEQ_ARG_VALUE_MASK (0xffff)
44
45 /*
46 * VTE_SEQ_ARG_INIT_DEFAULT:
47 *
48 * Returns: a parameter with default value
49 */
50 #define VTE_SEQ_ARG_INIT_DEFAULT (0)
51
52 /*
53 * VTE_SEQ_ARG_INIT:
54 * @value:
55 *
56 * Returns: a parameter with value @value
57 */
58 #define VTE_SEQ_ARG_INIT(value) ((value & VTE_SEQ_ARG_VALUE_MASK) | VTE_SEQ_ARG_FLAG_VALUE)
59
60 /*
61 * vte_seq_arg_init:
62 * @value:
63 *
64 * Returns: a #vte_seq_arg_t for @value, or with default value if @value is -1
65 */
vte_seq_arg_init(int value)66 static constexpr inline vte_seq_arg_t vte_seq_arg_init(int value)
67 {
68 if (value == -1)
69 return VTE_SEQ_ARG_INIT_DEFAULT;
70 else
71 return VTE_SEQ_ARG_INIT(value);
72 }
73
74 /*
75 * vte_seq_arg_push:
76 * @arg:
77 * @c: a value between 3/0 and 3/9 ['0' .. '9']
78 *
79 * Multiplies @arg by 10 and adds the numeric value of @c.
80 *
81 * After this, @arg has a value.
82 */
vte_seq_arg_push(vte_seq_arg_t * arg,uint32_t c)83 static inline void vte_seq_arg_push(vte_seq_arg_t* arg,
84 uint32_t c)
85 {
86 auto value = *arg & VTE_SEQ_ARG_VALUE_MASK;
87 value = value * 10 + (c - '0');
88
89 /*
90 * VT510 tells us to clamp all values to [0, 9999], however, it
91 * also allows commands with values up to 2^15-1. We simply use
92 * 2^16 as maximum here to be compatible to all commands, but
93 * avoid overflows in any calculations.
94 */
95 if (value > 0xffff)
96 value = 0xffff;
97
98 *arg = value | VTE_SEQ_ARG_FLAG_VALUE;
99 }
100
101 /*
102 * vte_seq_arg_finish:
103 * @arg:
104 * @finalise:
105 *
106 * Finishes @arg; after this no more vte_seq_arg_push() calls
107 * are allowed.
108 *
109 * If @nonfinal is %true, marks @arg as a nonfinal parameter, is,
110 * there are more subparameters after it.
111 */
vte_seq_arg_finish(vte_seq_arg_t * arg,bool nonfinal=false)112 static inline void vte_seq_arg_finish(vte_seq_arg_t* arg,
113 bool nonfinal = false)
114 {
115 if (nonfinal)
116 *arg |= VTE_SEQ_ARG_FLAG_NONFINAL;
117 }
118
vte_seq_arg_refinish(vte_seq_arg_t * arg,bool nonfinal=false)119 static inline void vte_seq_arg_refinish(vte_seq_arg_t* arg,
120 bool nonfinal = false)
121 {
122 if (nonfinal)
123 *arg |= VTE_SEQ_ARG_FLAG_NONFINAL;
124 else
125 *arg &= ~VTE_SEQ_ARG_FLAG_NONFINAL;
126 }
127
128 /*
129 * vte_seq_arg_started:
130 * @arg:
131 *
132 * Returns: whether @arg has nondefault value
133 */
vte_seq_arg_started(vte_seq_arg_t arg)134 static constexpr inline bool vte_seq_arg_started(vte_seq_arg_t arg)
135 {
136 return arg & VTE_SEQ_ARG_FLAG_VALUE;
137 }
138
139 /*
140 * vte_seq_arg_default:
141 * @arg:
142 *
143 * Returns: whether @arg has default value
144 */
vte_seq_arg_default(vte_seq_arg_t arg)145 static constexpr inline bool vte_seq_arg_default(vte_seq_arg_t arg)
146 {
147 return !(arg & VTE_SEQ_ARG_FLAG_VALUE);
148 }
149
150 /*
151 * vte_seq_arg_nonfinal:
152 * @arg:
153 *
154 * Returns: whether @arg is a nonfinal parameter, i.e. there
155 * are more subparameters after it
156 */
vte_seq_arg_nonfinal(vte_seq_arg_t arg)157 static constexpr inline int vte_seq_arg_nonfinal(vte_seq_arg_t arg)
158 {
159 return (arg & VTE_SEQ_ARG_FLAG_NONFINAL);
160 }
161
162 /*
163 * vte_seq_arg_value:
164 * @arg:
165 * @default_value: (defaults to -1)
166 *
167 * Returns: the value of @arg, or @default_value if @arg has default value
168 */
vte_seq_arg_value(vte_seq_arg_t arg,int default_value=-1)169 static constexpr inline int vte_seq_arg_value(vte_seq_arg_t arg,
170 int default_value = -1)
171 {
172 return (arg & VTE_SEQ_ARG_FLAG_VALUE) ? (arg & VTE_SEQ_ARG_VALUE_MASK) : default_value;
173 }
174
175 /*
176 * vte_seq_arg_value_final:
177 * @arg:
178 * @default_value: (defaults to -1)
179 *
180 * Returns: the value of @arg, or @default_value if @arg has default value or is not final
181 */
vte_seq_arg_value_final(vte_seq_arg_t arg,int default_value=-1)182 static constexpr inline int vte_seq_arg_value_final(vte_seq_arg_t arg,
183 int default_value = -1)
184 {
185 return ((arg & VTE_SEQ_ARG_FLAG_MASK) == VTE_SEQ_ARG_FLAG_VALUE) ? (arg & VTE_SEQ_ARG_VALUE_MASK) : default_value;
186 }
187