version 1.1, 2012/02/21 22:19:56
|
version 1.1.1.2, 2014/07/30 07:55:27
|
Line 1
|
Line 1
|
/* |
/* |
* output.c Output API |
* output.c Output API |
* |
* |
* Copyright (c) 2001-2005 Thomas Graf <tgraf@suug.ch> | * Copyright (c) 2001-2013 Thomas Graf <tgraf@suug.ch> |
| * Copyright (c) 2013 Red Hat, Inc. |
* |
* |
* Permission is hereby granted, free of charge, to any person obtaining a |
* Permission is hereby granted, free of charge, to any person obtaining a |
* copy of this software and associated documentation files (the "Software"), |
* copy of this software and associated documentation files (the "Software"), |
Line 24
|
Line 25
|
|
|
#include <bmon/bmon.h> |
#include <bmon/bmon.h> |
#include <bmon/output.h> |
#include <bmon/output.h> |
|
#include <bmon/module.h> |
#include <bmon/conf.h> |
#include <bmon/conf.h> |
#include <bmon/node.h> | #include <bmon/group.h> |
#include <bmon/signal.h> | |
#include <bmon/utils.h> |
#include <bmon/utils.h> |
|
|
static struct output_module *reg_pri_list; | static struct bmon_subsys output_subsys; |
static struct output_module *reg_sec_list; | |
static struct output_module *preferred; | |
|
|
static inline void | void output_register(struct bmon_module *m) |
__regiter_output_module(struct output_module *ops, struct output_module **list) | |
{ |
{ |
ops->om_next = *list; | module_register(&output_subsys, m); |
*list = ops; | |
} |
} |
|
|
void register_output_module(struct output_module *ops) | static void activate_default(void) |
{ |
{ |
__regiter_output_module(ops, ®_pri_list); | /* |
} | * Try to activate a default output module if the user did not make |
| * a selection |
| */ |
| if (!output_subsys.s_nmod) { |
| struct bmon_module *m; |
|
|
void register_secondary_output_module(struct output_module *ops) | if (!output_set("curses")) |
{ | return; |
__regiter_output_module(ops, ®_sec_list); | |
} | |
|
|
static inline struct output_module * | if (!output_set("ascii")) |
__get_output_module(const char *name, struct output_module *list) | return; |
{ | |
struct output_module *i; | |
|
|
for (i = list; i; i = i->om_next) | /* Fall back to anything that could act as default */ |
if (!strcmp(i->om_name, name)) | list_for_each_entry(m, &output_subsys.s_mod_list, m_list) { |
return i; | if (m->m_flags & BMON_MODULE_DEFAULT) |
| if (!output_set(m->m_name)) |
| return; |
| } |
|
|
return NULL; | quit("No output module found\n"); |
| } |
} |
} |
|
|
static struct output_module * get_output_module(const char *name) |
|
{ |
|
return __get_output_module(name, reg_pri_list); |
|
} |
|
|
|
static struct output_module * get_sec_output_module(const char *name) |
|
{ |
|
return __get_output_module(name, reg_sec_list); |
|
} |
|
|
|
#define FOREACH_SOM(F) \ |
|
do { \ |
|
struct output_module *i; \ |
|
for (i = reg_sec_list; i; i = i->om_next) \ |
|
if (i->om_enable && i->om_##F) \ |
|
i->om_##F (); \ |
|
} while (0) |
|
|
|
const char * get_preferred_output_name(void) |
|
{ |
|
return preferred ? preferred->om_name : "none"; |
|
} |
|
|
|
static void find_preferred(int quiet) |
|
{ |
|
if (NULL == preferred) |
|
preferred = get_output_module("curses"); |
|
|
|
if (NULL == preferred) |
|
preferred = get_output_module("ascii"); |
|
|
|
if (NULL == preferred && !quiet) |
|
quit("No output module found.\n"); |
|
} |
|
|
|
void output_init(void) |
|
{ |
|
find_preferred(0); |
|
|
|
if (preferred->om_init) |
|
preferred->om_init(); |
|
|
|
FOREACH_SOM(init); |
|
} |
|
|
|
void output_pre(void) |
void output_pre(void) |
{ |
{ |
find_preferred(0); | module_foreach_run_enabled_pre(&output_subsys); |
| |
if (preferred->om_pre) | |
preferred->om_pre(); | |
| |
FOREACH_SOM(pre); | |
} |
} |
|
|
void output_draw(void) |
void output_draw(void) |
{ |
{ |
if (get_signal_output()) | module_foreach_run_enabled(&output_subsys); |
if (!is_signal_recvd()) | |
return; | |
| |
find_preferred(0); | |
| |
calc_node_rates(); | |
| |
if (preferred->om_draw) | |
preferred->om_draw(); | |
| |
FOREACH_SOM(draw); | |
} |
} |
|
|
void output_post(void) |
void output_post(void) |
{ |
{ |
find_preferred(0); | module_foreach_run_enabled_post(&output_subsys); |
| |
if (preferred->om_post) | |
preferred->om_post(); | |
| |
FOREACH_SOM(post); | |
} |
} |
|
|
void output_shutdown(void) | int output_set(const char *name) |
{ |
{ |
find_preferred(1); | return module_set(&output_subsys, name); |
| |
if (preferred && preferred->om_shutdown) | |
preferred->om_shutdown(); | |
| |
FOREACH_SOM(shutdown); | |
} |
} |
|
|
static void list_output(void) | static struct bmon_subsys output_subsys = { |
{ | .s_name = "output", |
struct output_module *o; | .s_activate_default = &activate_default, |
| .s_mod_list = LIST_SELF(output_subsys.s_mod_list), |
| }; |
|
|
printf("Output modules:\n"); | static void __init __output_init(void) |
if (NULL == reg_pri_list) | |
printf("\tNo output modules found.\n"); | |
else | |
for (o = reg_pri_list; o; o = o->om_next) | |
printf("\t%s\n", o->om_name); | |
} | |
| |
void set_output(const char *name) | |
{ |
{ |
static int set = 0; | return module_register_subsys(&output_subsys); |
module_conf_t *ml, *m; | |
| |
if (set) | |
return; | |
set = 1; | |
| |
if (NULL == name || !strcasecmp(name, "list")) { | |
list_output(); | |
exit(0); | |
} | |
| |
ml = parse_module_param(name); | |
| |
for (m = ml; m; m = m->next) { | |
preferred = get_output_module(ml->name); | |
| |
if (NULL == preferred) | |
continue; | |
| |
if (preferred->om_set_opts) | |
preferred->om_set_opts(ml->attrs); | |
| |
if (preferred->om_probe) | |
if (preferred->om_probe()) | |
return; | |
} | |
| |
quit("No (working) output module found\n"); | |
} | |
| |
static void list_sec_output(void) | |
{ | |
struct output_module *o; | |
| |
printf("Secondary output modules:\n"); | |
if (NULL == reg_sec_list) | |
printf("\tNo secondary output modules found.\n"); | |
else | |
for (o = reg_sec_list; o; o = o->om_next) | |
printf("\t%s\n", o->om_name); | |
} | |
| |
void set_sec_output(const char *name) | |
{ | |
module_conf_t *ml, *m; | |
| |
if (NULL == name || !strcasecmp(name, "list")) { | |
list_sec_output(); | |
exit(0); | |
} | |
| |
ml = parse_module_param(name); | |
| |
for (m = ml; m; m = m->next) { | |
struct output_module *o = get_sec_output_module(m->name); | |
| |
if (NULL == o) | |
continue; | |
| |
if (o->om_set_opts) | |
o->om_set_opts(ml->attrs); | |
| |
if (o->om_probe) { | |
if (o->om_probe() == 1) | |
o->om_enable = 1; | |
} | |
} | |
} | |
| |
void output_resize(void) | |
{ | |
find_preferred(0); | |
| |
if (preferred && preferred->om_resize) | |
preferred->om_resize(); | |
| |
FOREACH_SOM(resize); | |
} | |
| |
int resized; | |
| |
int got_resized(void) | |
{ | |
int ret = resized; | |
resized = 0; | |
return ret; | |
} |
} |