degesch: start using "on_change" notifications
Terminal attributes can be changed on the fly now.
This commit is contained in:
parent
34c1df5171
commit
3a922c3c1a
18
common.c
18
common.c
@ -1911,8 +1911,6 @@ config_schema_initialize_item (struct config_schema *schema,
|
||||
|
||||
item->schema = schema;
|
||||
item->user_data = user_data;
|
||||
if (schema->on_change)
|
||||
schema->on_change (item);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1924,6 +1922,22 @@ config_schema_apply_to_object (struct config_schema *schema_array,
|
||||
config_schema_initialize_item (schema_array++, object, user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
config_schema_call_changed (struct config_item_ *item)
|
||||
{
|
||||
if (item->type == CONFIG_ITEM_OBJECT)
|
||||
{
|
||||
struct str_map_iter iter;
|
||||
str_map_iter_init (&iter, &item->value.object);
|
||||
|
||||
struct config_item_ *child;
|
||||
while ((child = str_map_iter_next (&iter)))
|
||||
config_schema_call_changed (child);
|
||||
}
|
||||
else if (item->schema && item->schema->on_change)
|
||||
item->schema->on_change (item);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
||||
// XXX: this doesn't necessarily have to be well designed at all
|
||||
|
77
degesch.c
77
degesch.c
@ -1288,6 +1288,8 @@ server_destroy (void *self)
|
||||
|
||||
struct app_context
|
||||
{
|
||||
char *attrs_defaults[ATTR_COUNT]; ///< Default terminal attributes
|
||||
|
||||
// Configuration:
|
||||
|
||||
struct config config; ///< Program configuration
|
||||
@ -1380,7 +1382,10 @@ app_context_free (struct app_context *self)
|
||||
{
|
||||
config_free (&self->config);
|
||||
for (size_t i = 0; i < ATTR_COUNT; i++)
|
||||
{
|
||||
free (self->attrs_defaults[i]);
|
||||
free (self->attrs[i]);
|
||||
}
|
||||
|
||||
LIST_FOR_EACH (struct buffer, iter, self->buffers)
|
||||
{
|
||||
@ -1411,7 +1416,8 @@ static bool irc_is_this_us (struct server *s, const char *prefix);
|
||||
|
||||
// --- Configuration -----------------------------------------------------------
|
||||
|
||||
// TODO: eventually add "on_change" callbacks
|
||||
// TODO: "on_change" callbacks for everything
|
||||
static void on_config_attribute_change (struct config_item_ *item);
|
||||
|
||||
static bool
|
||||
config_validate_nonjunk_string
|
||||
@ -1565,7 +1571,8 @@ static struct config_schema g_config_behaviour[] =
|
||||
|
||||
static struct config_schema g_config_attributes[] =
|
||||
{
|
||||
#define XX(x, y, z) { .name = y, .comment = z, .type = CONFIG_ITEM_STRING },
|
||||
#define XX(x, y, z) { .name = y, .comment = z, .type = CONFIG_ITEM_STRING, \
|
||||
.on_change = on_config_attribute_change },
|
||||
ATTR_TABLE (XX)
|
||||
#undef XX
|
||||
{}
|
||||
@ -1862,7 +1869,7 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt,
|
||||
}
|
||||
|
||||
static void
|
||||
init_attribute (struct app_context *ctx, int id, const char *default_)
|
||||
on_config_attribute_change (struct config_item_ *item)
|
||||
{
|
||||
static const char *table[ATTR_COUNT] =
|
||||
{
|
||||
@ -1871,19 +1878,22 @@ init_attribute (struct app_context *ctx, int id, const char *default_)
|
||||
#undef XX
|
||||
};
|
||||
|
||||
const char *user = get_config_string (ctx->config.root, table[id]);
|
||||
if (user)
|
||||
ctx->attrs[id] = xstrdup (user);
|
||||
else
|
||||
ctx->attrs[id] = xstrdup (default_);
|
||||
struct app_context *ctx = item->user_data;
|
||||
for (int id = 0; id < ATTR_COUNT; id++)
|
||||
{
|
||||
const char *user = get_config_string (ctx->config.root, table[id]);
|
||||
free (ctx->attrs[id]);
|
||||
ctx->attrs[id] = xstrdup (user ? user : ctx->attrs_defaults[id]);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
init_colors (struct app_context *ctx)
|
||||
{
|
||||
bool have_ti = init_terminal ();
|
||||
char **defaults = ctx->attrs_defaults;
|
||||
|
||||
#define INIT_ATTR(id, ti) init_attribute (ctx, ATTR_ ## id, have_ti ? (ti) : "")
|
||||
#define INIT_ATTR(id, ti) defaults[ATTR_ ## id] = xstrdup (have_ti ? (ti) : "")
|
||||
|
||||
INIT_ATTR (PROMPT, enter_bold_mode);
|
||||
INIT_ATTR (RESET, exit_attribute_mode);
|
||||
@ -1913,6 +1923,10 @@ init_colors (struct app_context *ctx)
|
||||
}
|
||||
|
||||
g_log_message_real = log_message_attributed;
|
||||
|
||||
// Apply the default values so that we start with any formatting at all
|
||||
config_schema_call_changed
|
||||
(config_item_get (ctx->config.root, "attributes", NULL));
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@ -8343,7 +8357,7 @@ load_configuration_file (const char *filename, struct error **e)
|
||||
struct error *error = NULL;
|
||||
if (!(root = config_item_parse (data.str, data.len, false, &error)))
|
||||
{
|
||||
error_set (e, "configuration parse error: %s", error->message);
|
||||
error_set (e, "Configuration parse error: %s", error->message);
|
||||
error_free (error);
|
||||
}
|
||||
end:
|
||||
@ -8361,20 +8375,21 @@ load_configuration (struct app_context *ctx)
|
||||
if (filename)
|
||||
root = load_configuration_file (filename, &e);
|
||||
else
|
||||
print_status ("configuration file not found");
|
||||
log_global_error (ctx, "Configuration file not found");
|
||||
free (filename);
|
||||
|
||||
if (e)
|
||||
{
|
||||
print_error ("%s", e->message);
|
||||
log_global_error (ctx, "#s", e->message);
|
||||
error_free (e);
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
config_load (&ctx->config, root ? root : config_item_object ());
|
||||
|
||||
ctx->isolate_buffers =
|
||||
get_config_boolean (ctx->config.root, "behaviour.isolate_buffers");
|
||||
if (root)
|
||||
{
|
||||
config_item_destroy (ctx->config.root);
|
||||
ctx->config.root = NULL;
|
||||
config_load (&ctx->config, root);
|
||||
log_global_status (ctx, "Configuration loaded");
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
@ -8408,8 +8423,8 @@ load_server_from_config (struct app_context *ctx,
|
||||
buffer_add (ctx, buffer);
|
||||
buffer_activate (ctx, buffer);
|
||||
|
||||
// This fires any "on_change" callbacks
|
||||
config_schema_apply_to_object (g_config_server, subtree, s);
|
||||
config_schema_call_changed (subtree);
|
||||
|
||||
// XXX: is this desirable in here? I think we should do it only when
|
||||
// actually creating a new server instead of every time we load them.
|
||||
@ -8427,7 +8442,7 @@ load_server_from_config (struct app_context *ctx,
|
||||
}
|
||||
|
||||
static void
|
||||
init_servers (struct app_context *ctx)
|
||||
load_servers (struct app_context *ctx)
|
||||
{
|
||||
struct config_item_ *servers =
|
||||
config_item_get (ctx->config.root, "servers", NULL);
|
||||
@ -8713,14 +8728,26 @@ main (int argc, char *argv[])
|
||||
SSL_load_error_strings ();
|
||||
atexit (ERR_free_strings);
|
||||
|
||||
setup_signal_handlers ();
|
||||
// Bootstrap configuration, so that we can access schema items at all
|
||||
register_config_modules (&ctx);
|
||||
config_load (&ctx.config, config_item_object ());
|
||||
|
||||
// The following part is a bit brittle because of interdependencies
|
||||
setup_signal_handlers ();
|
||||
init_colors (&ctx);
|
||||
init_global_buffer (&ctx);
|
||||
init_poller_events (&ctx);
|
||||
load_configuration (&ctx);
|
||||
|
||||
init_colors (&ctx);
|
||||
init_poller_events (&ctx);
|
||||
init_global_buffer (&ctx);
|
||||
init_servers (&ctx);
|
||||
// TODO: this won't be needed after adding an "on_change" callback
|
||||
ctx.isolate_buffers =
|
||||
get_config_boolean (ctx.config.root, "behaviour.isolate_buffers");
|
||||
|
||||
// At this moment we can safely call any "on_change" callbacks
|
||||
config_schema_call_changed (ctx.config.root);
|
||||
|
||||
// Finally, we juice the configuration for some servers to create
|
||||
load_servers (&ctx);
|
||||
|
||||
refresh_prompt (&ctx);
|
||||
input_start (&ctx.input, argv[0]);
|
||||
|
Loading…
Reference in New Issue
Block a user