ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
settings.c
Go to the documentation of this file.
1
13#include "session/settings.h"
14#include <ascii-chat/common.h>
18
19#include <string.h>
20#include <time.h>
21
22/* ============================================================================
23 * Session Settings Functions
24 * ============================================================================ */
25
27 if (!settings) {
28 return;
29 }
30
31 memset(settings, 0, sizeof(session_settings_t));
32
33 // Read all defaults from the RCU options system
34 settings->version = 0;
35 settings->width = (int16_t)terminal_get_effective_width();
36 settings->height = (int16_t)terminal_get_effective_height();
37 settings->color_mode = (uint8_t)GET_OPTION(color_mode);
38 settings->render_mode = (uint8_t)GET_OPTION(render_mode);
39 settings->palette_type = (uint8_t)GET_OPTION(palette_type);
40
41 // Custom palette
42 const char *palette = GET_OPTION(palette_custom);
43 if (palette && palette[0] != '\0') {
44 SAFE_STRNCPY(settings->palette_custom, palette, sizeof(settings->palette_custom));
45 }
46
47 settings->audio_enabled = (uint8_t)GET_OPTION(audio_enabled);
48 settings->encryption_required = GET_OPTION(no_encrypt) ? 0 : 1;
49}
50
52 if (!settings || !buffer || !len) {
53 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_serialize: NULL parameter");
54 }
55
56 // Fixed-size serialization format
57 size_t offset = 0;
58
59 // Version (4 bytes, network byte order)
60 uint32_t version_net = htonl(settings->version);
61 memcpy(buffer + offset, &version_net, sizeof(version_net));
62 offset += sizeof(version_net);
63
64 // Width (2 bytes, network byte order)
65 uint16_t width_net = htons((uint16_t)(settings->width & 0xFFFF));
66 memcpy(buffer + offset, &width_net, sizeof(width_net));
67 offset += sizeof(width_net);
68
69 // Height (2 bytes, network byte order)
70 uint16_t height_net = htons((uint16_t)(settings->height & 0xFFFF));
71 memcpy(buffer + offset, &height_net, sizeof(height_net));
72 offset += sizeof(height_net);
73
74 // Color mode (1 byte)
75 buffer[offset++] = settings->color_mode;
76
77 // Render mode (1 byte)
78 buffer[offset++] = settings->render_mode;
79
80 // Palette type (1 byte)
81 buffer[offset++] = settings->palette_type;
82
83 // Custom palette (32 bytes, null-padded)
84 memcpy(buffer + offset, settings->palette_custom, 32);
85 offset += 32;
86
87 // Audio enabled (1 byte)
88 buffer[offset++] = settings->audio_enabled;
89
90 // Encryption required (1 byte)
91 buffer[offset++] = settings->encryption_required;
92
93 // Reserved (16 bytes)
94 memcpy(buffer + offset, settings->reserved, 16);
95 offset += 16;
96
97 *len = offset;
98 return ASCIICHAT_OK;
99}
100
102 if (!buffer || !settings) {
103 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_deserialize: NULL parameter");
104 }
105
106 // Check minimum buffer size
108 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_deserialize: buffer too small (%zu < %d)", len,
110 }
111
112 memset(settings, 0, sizeof(session_settings_t));
113 size_t offset = 0;
114
115 // Version (4 bytes, network byte order)
116 uint32_t version_net;
117 memcpy(&version_net, buffer + offset, sizeof(version_net));
118 settings->version = ntohl(version_net);
119 offset += sizeof(version_net);
120
121 // Width (2 bytes, network byte order)
122 uint16_t width_net;
123 memcpy(&width_net, buffer + offset, sizeof(width_net));
124 settings->width = (int16_t)ntohs(width_net);
125 offset += sizeof(width_net);
126
127 // Height (2 bytes, network byte order)
128 uint16_t height_net;
129 memcpy(&height_net, buffer + offset, sizeof(height_net));
130 settings->height = (int16_t)ntohs(height_net);
131 offset += sizeof(height_net);
132
133 // Color mode (1 byte)
134 settings->color_mode = buffer[offset++];
135
136 // Render mode (1 byte)
137 settings->render_mode = buffer[offset++];
138
139 // Palette type (1 byte)
140 settings->palette_type = buffer[offset++];
141
142 // Custom palette (32 bytes)
143 memcpy(settings->palette_custom, buffer + offset, 32);
144 settings->palette_custom[31] = '\0'; // Ensure null termination
145 offset += 32;
146
147 // Audio enabled (1 byte)
148 settings->audio_enabled = buffer[offset++];
149
150 // Encryption required (1 byte)
151 settings->encryption_required = buffer[offset++];
152
153 // Reserved (16 bytes)
154 memcpy(settings->reserved, buffer + offset, 16);
155 // offset += 16; // Unused, commented to avoid warning
156
157 return ASCIICHAT_OK;
158}
159
161 if (!settings) {
162 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_from_options: NULL settings");
163 }
164
165 // Initialize to defaults
166 session_settings_init(settings);
167
168 // Get current options
169 const options_t *opts = options_get();
170 if (!opts) {
171 return SET_ERRNO(ERROR_CONFIG, "Options not initialized");
172 }
173
174 // Set version to current time for ordering
175 settings->version = (uint32_t)time(NULL);
176
177 // Copy dimension settings
178 settings->width = (int16_t)opts->width;
179 settings->height = (int16_t)opts->height;
180
181 // Copy display settings
182 settings->color_mode = (uint8_t)opts->color_mode;
183 settings->render_mode = (uint8_t)opts->render_mode;
184 settings->palette_type = (uint8_t)opts->palette_type;
185
186 // Copy custom palette if set
187 if (opts->palette_custom_set && opts->palette_custom[0] != '\0') {
188 SAFE_STRNCPY(settings->palette_custom, opts->palette_custom, sizeof(settings->palette_custom));
189 }
190
191 // Copy audio/encryption settings
192 settings->audio_enabled = (uint8_t)opts->audio_enabled;
193 settings->encryption_required = opts->no_encrypt ? 0 : 1;
194
195 return ASCIICHAT_OK;
196}
197
199 if (!settings) {
200 return SET_ERRNO(ERROR_INVALID_PARAM, "session_settings_apply_to_options: NULL settings");
201 }
202
203 // Update dimensions if specified
204 if (settings->width > 0 && settings->height > 0) {
205 asciichat_error_t width_result = options_set_int("width", (int)settings->width);
206 asciichat_error_t height_result = options_set_int("height", (int)settings->height);
207 if (width_result != ASCIICHAT_OK || height_result != ASCIICHAT_OK) {
208 log_warn("Failed to apply dimension settings: width=%d, height=%d", width_result, height_result);
209 }
210 }
211
212 // Note: Other options would require additional RCU update functions
213 // For now, dimensions are the primary use case for runtime updates
214 // Color mode, render mode, and palette typically don't change mid-session
215
216 return ASCIICHAT_OK;
217}
218
219bool session_settings_needs_update(uint32_t local_version, uint32_t remote_version) {
220 // Higher version wins (newer settings)
221 return remote_version > local_version;
222}
223
225 if (!a || !b) {
226 return false;
227 }
228
229 // Compare all fields except version
230 return a->width == b->width && a->height == b->height && a->color_mode == b->color_mode &&
231 a->render_mode == b->render_mode && a->palette_type == b->palette_type &&
232 strncmp(a->palette_custom, b->palette_custom, sizeof(a->palette_custom)) == 0 &&
234}
⚠️‼️ Comprehensive thread-local error context system for ascii-chat
⚙️ Common definitions, error codes, macros, and types shared throughout the application
unsigned short uint16_t
Definition common.h:57
unsigned int uint32_t
Definition common.h:58
#define SAFE_STRNCPY(dst, src, size)
Definition common.h:414
unsigned char uint8_t
Definition common.h:56
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_CONFIG
Definition error_codes.h:57
@ ERROR_INVALID_PARAM
#define log_warn(...)
Log a WARN message.
Definition log/log.h:574
#define GET_OPTION(field)
Safely get a specific option field (lock-free read)
asciichat_error_t options_set_int(const char *field_name, int value)
Check if an option was explicitly set via command-line.
Definition rcu.c:761
const options_t * options_get(void)
Get current options (lock-free read)
Definition rcu.c:496
bool session_settings_equal(const session_settings_t *a, const session_settings_t *b)
Compare two settings structures for equality.
Definition settings.c:224
asciichat_error_t session_settings_deserialize(const uint8_t *buffer, size_t len, session_settings_t *settings)
Deserialize session settings from binary buffer.
Definition settings.c:101
asciichat_error_t session_settings_apply_to_options(const session_settings_t *settings)
Apply settings to global options.
Definition settings.c:198
bool session_settings_needs_update(uint32_t local_version, uint32_t remote_version)
Check if settings need update based on versions.
Definition settings.c:219
asciichat_error_t session_settings_from_options(session_settings_t *settings)
Populate settings from current global options.
Definition settings.c:160
asciichat_error_t session_settings_serialize(const session_settings_t *settings, uint8_t *buffer, size_t *len)
Serialize session settings to binary buffer.
Definition settings.c:51
void session_settings_init(session_settings_t *settings)
Initialize session settings to defaults.
Definition settings.c:26
#define SESSION_SETTINGS_SERIALIZED_SIZE
Size of serialized session settings in bytes.
Definition settings.h:59
⚙️ Unified options parsing system for ascii-chat with builder pattern and lock-free access
Cross-platform network headers and socket definitions.
unsigned short int terminal_get_effective_width(void)
Get effective terminal width with fallback priority.
unsigned short int terminal_get_effective_height(void)
Get effective terminal height with fallback priority.
⚙️ Session settings serialization and synchronization
Consolidated options structure.
terminal_color_mode_t color_mode
Color mode (auto/none/16/256/truecolor)
int height
Terminal height in characters (int for OPTION_TYPE_INT compat)
bool audio_enabled
Enable audio streaming.
bool no_encrypt
Disable encryption (opt-out)
char palette_custom[256]
Custom palette characters.
bool palette_custom_set
True if custom palette was set.
render_mode_t render_mode
Render mode (foreground/background/half-block)
int width
Terminal width in characters (int for OPTION_TYPE_INT compat)
palette_type_t palette_type
Selected palette type.
Session settings for transmission between peers.
Definition settings.h:77
uint8_t audio_enabled
Audio enabled flag.
Definition settings.h:100
char palette_custom[32]
Custom palette characters (if palette_type == PALETTE_CUSTOM)
Definition settings.h:97
int16_t width
Terminal width in characters (0 = auto-detect)
Definition settings.h:82
uint8_t color_mode
Color mode (terminal_color_mode_t value)
Definition settings.h:88
uint8_t palette_type
Palette type (palette_type_t value)
Definition settings.h:94
uint8_t encryption_required
Encryption required flag.
Definition settings.h:103
uint32_t version
Settings version for conflict detection (monotonically increasing)
Definition settings.h:79
uint8_t render_mode
Render mode (render_mode_t value)
Definition settings.h:91
uint8_t reserved[16]
Reserved bytes for future expansion.
Definition settings.h:106
int16_t height
Terminal height in characters (0 = auto-detect)
Definition settings.h:85
⏱️ High-precision timing utilities using sokol_time.h and uthash