/*
* Event Loop
*
- * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
* Copyright (c) 2011 University of Tuebingen
*
* Permission is hereby granted, free of charge, to any person obtaining
* ev_eloop:
* @ref: refcnt of this object
* @llog: llog log function
+ * @llog_data: llog log function user-data
* @efd: The epoll file descriptor.
* @fd: Event source around \efd so you can nest event loops
* @cnt: Counter source used for idle events
struct ev_eloop {
unsigned long ref;
llog_submit_t llog;
+ void *llog_data;
int efd;
struct ev_fd *fd;
int idle_fd;
* ev_fd:
* @ref: refcnt for object
* @llog: llog log function
+ * @llog_data: llog log function user-data
* @fd: the actual file desciptor
* @mask: the event mask for this fd (EV_READABLE, EV_WRITABLE, ...)
* @cb: the user callback
struct ev_fd {
unsigned long ref;
llog_submit_t llog;
+ void *llog_data;
int fd;
int mask;
ev_fd_cb cb;
* ev_timer:
* @ref: refcnt of this object
* @llog: llog log function
+ * @llog_data: llog log function user-data
* @cb: user callback
* @data: user data
* @fd: the timerfd file desciptor
struct ev_timer {
unsigned long ref;
llog_submit_t llog;
+ void *llog_data;
ev_timer_cb cb;
void *data;
* ev_counter:
* @ref: refcnt of counter object
* @llog: llog log function
+ * @llog_data: llog log function user-data
* @cb: user callback
* @data: user data
* @fd: eventfd file desciptor
struct ev_counter {
unsigned long ref;
llog_submit_t llog;
+ void *llog_data;
ev_counter_cb cb;
void *data;
llog_warn(eloop, "HUP/ERR on eloop source");
}
-static int write_eventfd(llog_submit_t llog, int fd, uint64_t val)
+static int write_eventfd(llog_submit_t llog, void *llog_data, int fd,
+ uint64_t val)
{
int ret;
if (!val)
- return llog_dEINVAL(llog);
+ return llog_dEINVAL(llog, llog_data);
if (val == 0xffffffffffffffffULL) {
- llog_dwarning(llog, "increasing counter with invalid value %" PRIu64, val);
+ llog_dwarning(llog, llog_data,
+ "increasing counter with invalid value %" PRIu64,
+ val);
return -EINVAL;;
}
ret = write(fd, &val, sizeof(val));
if (ret < 0) {
if (errno == EAGAIN)
- llog_dwarning(llog, "eventfd overflow while writing %" PRIu64, val);
+ llog_dwarning(llog, llog_data,
+ "eventfd overflow while writing %" PRIu64,
+ val);
else
- llog_dwarning(llog, "eventfd write error (%d): %m", errno);
+ llog_dwarning(llog, llog_data,
+ "eventfd write error (%d): %m", errno);
return -EFAULT;
} else if (ret != sizeof(val)) {
- llog_dwarning(llog, "wrote %d bytes instead of 8 to eventdfd", ret);
+ llog_dwarning(llog, llog_data,
+ "wrote %d bytes instead of 8 to eventdfd", ret);
return -EFAULT;
}
} else if (val > 0) {
shl_hook_call(loop->idlers, loop, NULL);
if (shl_hook_num(loop->idlers) > 0)
- write_eventfd(loop->llog, loop->idle_fd, 1);
+ write_eventfd(loop->llog, loop->llog_data,
+ loop->idle_fd, 1);
}
return;
* ev_eloop_new:
* @out: Storage for the result
* @log: logging function or NULL
+ * @log_data: logging function user-data
*
* This creates a new event-loop with ref-count 1. The new event loop is stored
* in @out and has no registered events.
* Returns: 0 on success, otherwise negative error code
*/
SHL_EXPORT
-int ev_eloop_new(struct ev_eloop **out, ev_log_t log)
+int ev_eloop_new(struct ev_eloop **out, ev_log_t log, void *log_data)
{
struct ev_eloop *loop;
int ret;
struct epoll_event ep;
if (!out)
- return llog_dEINVAL(log);
+ return llog_dEINVAL(log, log_data);
loop = malloc(sizeof(*loop));
if (!loop)
- return llog_dENOMEM(log);
+ return llog_dENOMEM(log, log_data);
memset(loop, 0, sizeof(*loop));
loop->ref = 1;
loop->llog = log;
+ loop->llog_data = log_data;
shl_dlist_init(&loop->sig_list);
loop->cur_fds_size = 32;
}
ret = ev_fd_new(&loop->fd, loop->efd, EV_READABLE, eloop_event, loop,
- loop->llog);
+ loop->llog, loop->llog_data);
if (ret)
goto err_close;
if (!out)
return llog_EINVAL(loop);
- ret = ev_eloop_new(&el, loop->llog);
+ ret = ev_eloop_new(&el, loop->llog, loop->llog_data);
if (ret)
return ret;
* @cb: User callback
* @data: User data
* @log: llog function or NULL
+ * @log_data: logging function user-data
*
* This creates a new file desciptor source that is watched for the events set
* in @mask. @rfd is the system filedescriptor. The resulting object is stored
*/
SHL_EXPORT
int ev_fd_new(struct ev_fd **out, int rfd, int mask, ev_fd_cb cb, void *data,
- ev_log_t log)
+ ev_log_t log, void *log_data)
{
struct ev_fd *fd;
if (!out || rfd < 0)
- return llog_dEINVAL(log);
+ return llog_dEINVAL(log, log_data);
fd = malloc(sizeof(*fd));
if (!fd)
- return llog_dEINVAL(log);
+ return llog_dEINVAL(log, log_data);
memset(fd, 0, sizeof(*fd));
fd->ref = 1;
fd->llog = log;
+ fd->llog_data = log_data;
fd->fd = rfd;
fd->mask = mask;
fd->cb = cb;
if (!out || rfd < 0)
return llog_EINVAL(loop);
- ret = ev_fd_new(&fd, rfd, mask, cb, data, loop->llog);
+ ret = ev_fd_new(&fd, rfd, mask, cb, data, loop->llog, loop->llog_data);
if (ret)
return ret;
* @cb: callback to use for this event-source
* @data: user-specified data
* @log: logging function or NULL
+ * @log_data: logging function user-data
*
* This creates a new timer-source. See "man timerfd_create" for information on
* the @spec argument. The timer is always relative and uses the
*/
SHL_EXPORT
int ev_timer_new(struct ev_timer **out, const struct itimerspec *spec,
- ev_timer_cb cb, void *data, ev_log_t log)
+ ev_timer_cb cb, void *data, ev_log_t log, void *log_data)
{
struct ev_timer *timer;
int ret;
if (!out)
- return llog_dEINVAL(log);
+ return llog_dEINVAL(log, log_data);
if (!spec)
spec = &ev_timer_zero;
timer = malloc(sizeof(*timer));
if (!timer)
- return llog_dENOMEM(log);
+ return llog_dENOMEM(log, log_data);
memset(timer, 0, sizeof(*timer));
timer->ref = 1;
timer->llog = log;
+ timer->llog_data = log_data;
timer->cb = cb;
timer->data = data;
}
ret = ev_fd_new(&timer->efd, timer->fd, EV_READABLE, timer_cb, timer,
- timer->llog);
+ timer->llog, timer->llog_data);
if (ret)
goto err_close;
if (!out)
return llog_EINVAL(loop);
- ret = ev_timer_new(&timer, spec, cb, data, loop->llog);
+ ret = ev_timer_new(&timer, spec, cb, data, loop->llog, loop->llog_data);
if (ret)
return ret;
* @cb: user-supplied callback
* @data: user-supplied data
* @log: logging function or NULL
+ * @log_data: logging function user-data
*
* This creates a new counter object and stores it in @out.
*
*/
SHL_EXPORT
int ev_counter_new(struct ev_counter **out, ev_counter_cb cb, void *data,
- ev_log_t log)
+ ev_log_t log, void *log_data)
{
struct ev_counter *cnt;
int ret;
if (!out)
- return llog_dEINVAL(log);
+ return llog_dEINVAL(log, log_data);
cnt = malloc(sizeof(*cnt));
if (!cnt)
- return llog_dENOMEM(log);
+ return llog_dENOMEM(log, log_data);
memset(cnt, 0, sizeof(*cnt));
cnt->ref = 1;
cnt->llog = log;
+ cnt->llog_data = log_data;
cnt->cb = cb;
cnt->data = data;
}
ret = ev_fd_new(&cnt->efd, cnt->fd, EV_READABLE, counter_event, cnt,
- cnt->llog);
+ cnt->llog, cnt->llog_data);
if (ret)
goto err_close;
if (!cnt)
return -EINVAL;
- return write_eventfd(cnt->llog, cnt->fd, val);
+ return write_eventfd(cnt->llog, cnt->llog_data, cnt->fd, val);
}
/**
if (!out)
return llog_EINVAL(eloop);
- ret = ev_counter_new(&cnt, cb, data, eloop->llog);
+ ret = ev_counter_new(&cnt, cb, data, eloop->llog, eloop->llog_data);
if (ret)
return ret;
if (ret)
return ret;
- ret = write_eventfd(eloop->llog, eloop->idle_fd, 1);
+ ret = write_eventfd(eloop->llog, eloop->llog_data, eloop->idle_fd, 1);
if (ret) {
llog_warning(eloop, "cannot increase eloop idle-counter");
shl_hook_rm_cast(eloop->idlers, cb, data);
/*
* Event Loop
*
- * Copyright (c) 2011-2012 David Herrmann <dh.herrmann@googlemail.com>
+ * Copyright (c) 2011-2013 David Herrmann <dh.herrmann@googlemail.com>
* Copyright (c) 2011 University of Tuebingen
*
* Permission is hereby granted, free of charge, to any person obtaining
/**
* ev_log_t:
+ * @data: User provided data field
* @file: Source code file where the log message originated or NULL
* @line: Line number in source code or 0
* @func: C function name or NULL
* This is the type of a logging callback function. You can always pass NULL
* instead of such a function to disable logging.
*/
-typedef void (*ev_log_t) (const char *file,
+typedef void (*ev_log_t) (void *data,
+ const char *file,
int line,
const char *func,
const char *subs,
EV_ET = 0x10,
};
-int ev_eloop_new(struct ev_eloop **out, ev_log_t log);
+int ev_eloop_new(struct ev_eloop **out, ev_log_t log, void *log_data);
void ev_eloop_ref(struct ev_eloop *loop);
void ev_eloop_unref(struct ev_eloop *loop);
/* fd sources */
int ev_fd_new(struct ev_fd **out, int fd, int mask, ev_fd_cb cb, void *data,
- ev_log_t log);
+ ev_log_t log, void *log_data);
void ev_fd_ref(struct ev_fd *fd);
void ev_fd_unref(struct ev_fd *fd);
/* timer sources */
int ev_timer_new(struct ev_timer **out, const struct itimerspec *spec,
- ev_timer_cb cb, void *data, ev_log_t log);
+ ev_timer_cb cb, void *data, ev_log_t log, void *log_data);
void ev_timer_ref(struct ev_timer *timer);
void ev_timer_unref(struct ev_timer *timer);
/* counter sources */
int ev_counter_new(struct ev_counter **out, ev_counter_cb, void *data,
- ev_log_t log);
+ ev_log_t log, void *log_data);
void ev_counter_ref(struct ev_counter *cnt);
void ev_counter_unref(struct ev_counter *cnt);
* the implementation between both instead of doing everything ourself
* here. */
- ret = tsm_screen_new(&client->screen, log_llog);
+ ret = tsm_screen_new(&client->screen, log_llog, NULL);
if (ret) {
log_error("cannot create TSM screen for new cdev client: %d",
ret);
}
ret = tsm_vte_new(&client->vte, client->screen, client_vte_event,
- client, log_llog);
+ client, log_llog, NULL);
if (ret) {
log_error("cannot create TSM VTE for new cdev client: %d",
ret);
shl_dlist_init(&app->seats);
- ret = ev_eloop_new(&app->eloop, log_llog);
+ ret = ev_eloop_new(&app->eloop, log_llog, NULL);
if (ret) {
log_error("cannot create eloop object: %d", ret);
goto err_app;
term->conf_ctx = kmscon_seat_get_conf(seat);
term->conf = conf_ctx_get_mem(term->conf_ctx);
- ret = tsm_screen_new(&term->console, log_llog);
+ ret = tsm_screen_new(&term->console, log_llog, NULL);
if (ret)
goto err_free;
tsm_screen_set_max_sb(term->console, term->conf->sb_size);
TSM_SCREEN_OPT_RENDER_TIMING);
ret = tsm_vte_new(&term->vte, term->console, write_event, term,
- log_llog);
+ log_llog, NULL);
if (ret)
goto err_con;
tsm_vte_set_palette(term->vte, term->conf->palette);
}
SHL_EXPORT
-void log_llog(const char *file,
+void log_llog(void *data,
+ const char *file,
int line,
const char *func,
const char *subs,
const char *format,
...);
-__attribute__((format(printf, 6, 0)))
-void log_llog(const char *file,
+__attribute__((format(printf, 7, 0)))
+void log_llog(void *data,
+ const char *file,
int line,
const char *func,
const char *subs,
pty->input_cb = input_cb;
pty->data = data;
- ret = ev_eloop_new(&pty->eloop, log_llog);
+ ret = ev_eloop_new(&pty->eloop, log_llog, NULL);
if (ret)
goto err_free;
* header. Instead, copy it into your application if you want and use it there.
* Your public library API should include something like this:
*
- * typedef void (*MYPREFIX_log_t) (const char *file,
+ * typedef void (*MYPREFIX_log_t) (void *data,
+ * const char *file,
* int line,
* const char *func,
* const char *subs,
* use the "llog" field to print the message. If it is NULL, nothing is done.
*
* The arguments of the log-function are defined as:
+ * data: User-supplied data field that is passed straight through.
* file: Zero terminated string of the file-name where the log-message
* occurred. Can be NULL.
* line: Line number of @file where the message occurred. Set to 0 or smaller
* themself, if they need it.
* format: Format string. Must not be NULL.
* args: Argument array
+ *
+ * The user should also be able to optionally provide a data field which is
+ * always passed unmodified as first parameter to the log-function. This allows
+ * to add context to the logger.
*/
#ifndef SHL_LLOG_H_INCLUDED
#define SHL_LLOG_H_INCLUDED
#include <stdarg.h>
+#include <stdbool.h>
#include <stdlib.h>
enum llog_severity {
LLOG_SEV_NUM,
};
-typedef void (*llog_submit_t) (const char *file,
+typedef void (*llog_submit_t) (void *data,
+ const char *file,
int line,
const char *func,
const char *subs,
const char *format,
va_list args);
-static inline __attribute__((format(printf, 7, 8)))
+static inline __attribute__((format(printf, 8, 9)))
void llog_format(llog_submit_t llog,
+ void *data,
const char *file,
int line,
const char *func,
if (llog) {
va_start(list, format);
- llog(file, line, func, subs, sev, format, list);
+ llog(data, file, line, func, subs, sev, format, list);
va_end(list);
}
}
#define LLOG_DEFAULT __FILE__, __LINE__, __func__, LLOG_SUBSYSTEM
#define llog_printf(obj, sev, format, ...) \
- llog_format((obj)->llog, LLOG_DEFAULT, (sev), (format), ##__VA_ARGS__)
-#define llog_dprintf(obj, sev, format, ...) \
- llog_format((obj), LLOG_DEFAULT, (sev), (format), ##__VA_ARGS__)
-
-static inline __attribute__((format(printf, 3, 4)))
-void llog_dummyf(llog_submit_t llog, unsigned int sev,
+ llog_format((obj)->llog, \
+ (obj)->llog_data, \
+ LLOG_DEFAULT, \
+ (sev), \
+ (format), \
+ ##__VA_ARGS__)
+#define llog_dprintf(obj, data, sev, format, ...) \
+ llog_format((obj), \
+ (data), \
+ LLOG_DEFAULT, \
+ (sev), \
+ (format), \
+ ##__VA_ARGS__)
+
+static inline __attribute__((format(printf, 4, 5)))
+void llog_dummyf(llog_submit_t llog, void *data, unsigned int sev,
const char *format, ...)
{
}
*/
#ifdef BUILD_ENABLE_DEBUG
- #define llog_ddebug(obj, format, ...) \
- llog_dprintf((obj), LLOG_DEBUG, (format), ##__VA_ARGS__)
+ #define llog_ddebug(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_DEBUG, (format), ##__VA_ARGS__)
#define llog_debug(obj, format, ...) \
- llog_ddebug((obj)->llog, (format), ##__VA_ARGS__)
+ llog_ddebug((obj)->llog, (obj)->llog_data, (format), ##__VA_ARGS__)
#else
- #define llog_ddebug(obj, format, ...) \
- llog_dummyf((obj), LLOG_DEBUG, (format), ##__VA_ARGS__)
+ #define llog_ddebug(obj, data, format, ...) \
+ llog_dummyf((obj), (data), LLOG_DEBUG, (format), ##__VA_ARGS__)
#define llog_debug(obj, format, ...) \
- llog_ddebug((obj)->llog, (format), ##__VA_ARGS__)
+ llog_ddebug((obj)->llog, (obj)->llog_data, (format), ##__VA_ARGS__)
#endif
#define llog_info(obj, format, ...) \
llog_printf((obj), LLOG_INFO, (format), ##__VA_ARGS__)
-#define llog_dinfo(obj, format, ...) \
- llog_dprintf((obj), LLOG_INFO, (format), ##__VA_ARGS__)
+#define llog_dinfo(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_INFO, (format), ##__VA_ARGS__)
#define llog_notice(obj, format, ...) \
llog_printf((obj), LLOG_NOTICE, (format), ##__VA_ARGS__)
-#define llog_dnotice(obj, format, ...) \
- llog_dprintf((obj), LLOG_NOTICE, (format), ##__VA_ARGS__)
+#define llog_dnotice(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_NOTICE, (format), ##__VA_ARGS__)
#define llog_warning(obj, format, ...) \
llog_printf((obj), LLOG_WARNING, (format), ##__VA_ARGS__)
-#define llog_dwarning(obj, format, ...) \
- llog_dprintf((obj), LLOG_WARNING, (format), ##__VA_ARGS__)
+#define llog_dwarning(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_WARNING, (format), ##__VA_ARGS__)
#define llog_error(obj, format, ...) \
llog_printf((obj), LLOG_ERROR, (format), ##__VA_ARGS__)
-#define llog_derror(obj, format, ...) \
- llog_dprintf((obj), LLOG_ERROR, (format), ##__VA_ARGS__)
+#define llog_derror(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_ERROR, (format), ##__VA_ARGS__)
#define llog_critical(obj, format, ...) \
llog_printf((obj), LLOG_CRITICAL, (format), ##__VA_ARGS__)
-#define llog_dcritical(obj, format, ...) \
- llog_dprintf((obj), LLOG_CRITICAL, (format), ##__VA_ARGS__)
+#define llog_dcritical(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_CRITICAL, (format), ##__VA_ARGS__)
#define llog_alert(obj, format, ...) \
llog_printf((obj), LLOG_ALERT, (format), ##__VA_ARGS__)
-#define llog_dalert(obj, format, ...) \
- llog_dprintf((obj), LLOG_ALERT, (format), ##__VA_ARGS__)
+#define llog_dalert(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_ALERT, (format), ##__VA_ARGS__)
#define llog_fatal(obj, format, ...) \
llog_printf((obj), LLOG_FATAL, (format), ##__VA_ARGS__)
-#define llog_dfatal(obj, format, ...) \
- llog_dprintf((obj), LLOG_FATAL, (format), ##__VA_ARGS__)
+#define llog_dfatal(obj, data, format, ...) \
+ llog_dprintf((obj), (data), LLOG_FATAL, (format), ##__VA_ARGS__)
#define llog_dbg llog_debug
#define llog_warn llog_warning
* are used in debug paths and would slow down normal applications.
*/
-#define llog_dEINVAL(obj) \
- (llog_ddebug((obj), "invalid arguments"), -EINVAL)
+#define llog_dEINVAL(obj, data) \
+ (llog_ddebug((obj), (data), "invalid arguments"), -EINVAL)
#define llog_EINVAL(obj) \
- (llog_dEINVAL((obj)->llog))
+ (llog_dEINVAL((obj)->llog, (obj)->llog_data))
#define llog_vEINVAL(obj) \
((void)llog_EINVAL(obj))
-#define llog_vdEINVAL(obj) \
- ((void)llog_dEINVAL(obj))
+#define llog_vdEINVAL(obj, data) \
+ ((void)llog_dEINVAL((obj), (data)))
-#define llog_dEFAULT(obj) \
- (llog_ddebug((obj), "operation failed"), -EFAULT)
+#define llog_dEFAULT(obj, data) \
+ (llog_ddebug((obj), (data), "operation failed"), -EFAULT)
#define llog_EFAULT(obj) \
- (llog_dEFAULT((obj)->llog))
+ (llog_dEFAULT((obj)->llog, (obj)->llog_data))
#define llog_vEFAULT(obj) \
((void)llog_EFAULT(obj))
-#define llog_vdEFAULT(obj) \
- ((void)llog_dEFAULT(obj))
+#define llog_vdEFAULT(obj, data) \
+ ((void)llog_dEFAULT((obj), (data)))
-#define llog_dENOMEM(obj) \
- (llog_ddebug((obj), "memory allocation failed"), -ENOMEM)
+#define llog_dENOMEM(obj, data) \
+ (llog_ddebug((obj), (data), "memory allocation failed"), -ENOMEM)
#define llog_ENOMEM(obj) \
- (llog_dENOMEM((obj)->llog))
+ (llog_dENOMEM((obj)->llog, (obj)->llog_data))
#define llog_vENOMEM(obj) \
((void)llog_ENOMEM(obj))
-#define llog_vdENOMEM(obj) \
- ((void)llog_dENOMEM(obj))
+#define llog_vdENOMEM(obj, data) \
+ ((void)llog_dENOMEM((obj), (data)))
#endif /* SHL_LLOG_H_INCLUDED */
struct gl_shader;
int gl_shader_new(struct gl_shader **out, const char *vert, const char *frag,
- char **attr, size_t attr_count, llog_submit_t llog);
+ char **attr, size_t attr_count, llog_submit_t llog,
+ void *llog_data);
void gl_shader_ref(struct gl_shader *shader);
void gl_shader_unref(struct gl_shader *shader);
GLuint gl_shader_get_uniform(struct gl_shader *shader, const char *name);
struct gl_shader {
unsigned long ref;
llog_submit_t llog;
+ void *llog_data;
GLuint program;
GLuint vshader;
}
int gl_shader_new(struct gl_shader **out, const char *vert, const char *frag,
- char **attr, size_t attr_count, llog_submit_t llog)
+ char **attr, size_t attr_count, llog_submit_t llog,
+ void *llog_data)
{
struct gl_shader *shader;
int ret, i;
memset(shader, 0, sizeof(*shader));
shader->ref = 1;
shader->llog = llog;
+ shader->llog_data = llog_data;
llog_debug(shader, "new shader");
gl_clear_error();
ret = gl_shader_new(>->shader, gl_static_gltex_vert,
- gl_static_gltex_frag, attr, 4, log_llog);
+ gl_static_gltex_frag, attr, 4, log_llog, NULL);
if (ret)
goto err_bold_htable;
struct tsm_screen {
size_t ref;
llog_submit_t llog;
+ void *llog_data;
unsigned int opts;
unsigned int flags;
struct shl_timer *timer;
}
SHL_EXPORT
-int tsm_screen_new(struct tsm_screen **out, tsm_log_t log)
+int tsm_screen_new(struct tsm_screen **out, tsm_log_t log, void *log_data)
{
struct tsm_screen *con;
int ret;
memset(con, 0, sizeof(*con));
con->ref = 1;
con->llog = log;
+ con->llog_data = log_data;
con->def_attr.fr = 255;
con->def_attr.fg = 255;
con->def_attr.fb = 255;
/**
* tsm_log_t:
+ * @data: user-provided data
* @file: Source code file where the log message originated or NULL
* @line: Line number in source code or 0
* @func: C function name or NULL
* This is the type of a logging callback function. You can always pass NULL
* instead of such a function to disable logging.
*/
-typedef void (*tsm_log_t) (const char *file,
+typedef void (*tsm_log_t) (void *data,
+ const char *file,
int line,
const char *func,
const char *subs,
typedef int (*tsm_screen_render_cb) (struct tsm_screen *con,
void *data);
-int tsm_screen_new(struct tsm_screen **out, tsm_log_t log);
+int tsm_screen_new(struct tsm_screen **out, tsm_log_t log, void *log_data);
void tsm_screen_ref(struct tsm_screen *con);
void tsm_screen_unref(struct tsm_screen *con);
struct tsm_vte {
unsigned long ref;
tsm_log_t llog;
+ void *llog_data;
struct tsm_screen *con;
tsm_vte_write_cb write_cb;
void *data;
SHL_EXPORT
int tsm_vte_new(struct tsm_vte **out, struct tsm_screen *con,
tsm_vte_write_cb write_cb, void *data,
- tsm_log_t log)
+ tsm_log_t log, void *log_data)
{
struct tsm_vte *vte;
int ret;
memset(vte, 0, sizeof(*vte));
vte->ref = 1;
vte->llog = log;
+ vte->llog_data = log_data;
vte->con = con;
vte->write_cb = write_cb;
vte->data = data;
int tsm_vte_new(struct tsm_vte **out, struct tsm_screen *con,
tsm_vte_write_cb write_cb, void *data,
- tsm_log_t log);
+ tsm_log_t log, void *log_data);
void tsm_vte_ref(struct tsm_vte *vte);
void tsm_vte_unref(struct tsm_vte *vte);
v3d->sinit = 1;
ret = gl_shader_new(&v3d->fill_shader, gl_static_fill_vert,
- gl_static_fill_frag, fill_attr, 2, log_llog);
+ gl_static_fill_frag, fill_attr, 2, log_llog, NULL);
if (ret)
return ret;
"projection");
ret = gl_shader_new(&v3d->blend_shader, gl_static_blend_vert,
- gl_static_blend_frag, blend_attr, 2, log_llog);
+ gl_static_blend_frag, blend_attr, 2, log_llog,
+ NULL);
if (ret)
return ret;
"bgcolor");
ret = gl_shader_new(&v3d->blit_shader, gl_static_blit_vert,
- gl_static_blit_frag, blit_attr, 2, log_llog);
+ gl_static_blit_frag, blit_attr, 2, log_llog, NULL);
if (ret)
return ret;
disp->vblank_spec.it_value.tv_nsec = 15 * 1000 * 1000;
ret = ev_timer_new(&disp->vblank_timer, NULL,
- display_vblank_timer_event, disp, NULL);
+ display_vblank_timer_event, disp, NULL, NULL);
if (ret)
goto err_hook;
{
int ret;
- ret = ev_eloop_new(&app->eloop, log_llog);
+ ret = ev_eloop_new(&app->eloop, log_llog, NULL);
if (ret)
goto err_app;
goto err_free;
}
- ret = tsm_screen_new(&term->scr, log_llog);
+ ret = tsm_screen_new(&term->scr, log_llog, NULL);
if (ret) {
log_error("cannot create tsm-screen object");
goto err_font;
}
tsm_screen_set_max_sb(term->scr, wlt_conf.sb_size);
- ret = tsm_vte_new(&term->vte, term->scr, vte_event, term, log_llog);
+ ret = tsm_vte_new(&term->vte, term->scr, vte_event, term, log_llog,
+ NULL);
if (ret) {
log_error("cannot create tsm-vte object");
goto err_scr;