1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-20 00:15:31 +00:00
elinks/src/main/event.h
2022-01-30 19:19:20 +01:00

134 lines
4.4 KiB
C

#ifndef EL__MAIN_EVENT_H
#define EL__MAIN_EVENT_H
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#endif
#define EVENT_NONE (-1)
/* This enum is returned by each event hook and determines whether we should
* go on in the chain or finish the event processing. You want to always
* return EVENT_HOOK_STATUS_NEXT. */
/* More about EVENT_HOOK_STATUS_LAST - it means the event will get stuck on YOU
* and won't ever get to any other hooks queued behind you. This is usually not
* what you want. When I have plugin doing X with some document being loaded,
* and then script doing Y with it and finally some internal gadget doing some
* final touching of the document (say, colors normalization or so, I'm pulling
* this off my head), you definitively want all of them to happen, no matter if
* they are all successful or all unsuccessful or part of them successful. The
* only exceptions I can think of are:
*
* * I really messed something up. Ie. I somehow managed to destroy the
* document I got on input, but at least I know I did. Others don't and they
* will crash, and the document is of no use anyway. So let me be the last one.
*
* * I discarded the event. Say I'm children-protection plugin and the innocent
* kid drove me (unintentionally, of course) to some adult site. So I catch
* the appropriate event as long as I know it is bad, and discard it. No luck,
* Jonny. Oh, wait, you are going to write *own* plugin...?!
*
* * I transformed the even to another one. Say user pressed a key and I'm the
* keybinding hook. So I've found the key in my keybinding table, thus I catch
* it, lazy_trigger (TODO) the appropriate specific event (ie. "quit") and of
* course discard the original one.
*
* --pasky */
enum evhook_status {
EVENT_HOOK_STATUS_NEXT,
EVENT_HOOK_STATUS_LAST,
};
/* The event hook prototype. Abide. */
typedef enum evhook_status (*event_hook_T)(va_list ap, void *data);
/* This is convenience macro for hooks. Not all hooks may use all of their
* parameters, but they usually have to fetch all of them. This silences
* compiler ranting about unused variables then. It is recommended to run this
* upon all the parameters (in case some of the get unused in future) like:
*
* evhook_use_params(param1 && param2 && param3);
*
* The compiler is probably going to optimize it away anyway. */
#define evhook_use_params(x) if (0 && (x)) ;
/*** The life of events */
/* This registers an event of name @name, allocating an id number for it. */
/* The function returns the id or negative number upon error. */
int register_event(const char *name);
/* This unregisters an event number @event, freeing the resources it
* occupied, chain of associated hooks and unallocating the event id for
* further recyclation.
* Bug 810: unregister_event has not yet been implemented. */
int unregister_event(int event);
int register_event_hook(int id, event_hook_T callback, int priority, void *data);
void unregister_event_hook(int id, event_hook_T callback);
/*** Interface for table driven event hooks maintainance */
struct event_hook_info {
const char *name;
int priority;
event_hook_T callback;
union {
const void *data;
void *adata;
};
};
#define NULL_EVENT_HOOK_INFO { NULL, 0, NULL, {NULL} }
void register_event_hooks(struct event_hook_info *hooks);
void unregister_event_hooks(struct event_hook_info *hooks);
/*** The events resolver */
/* This looks up the events table and returns the event id associated
* with a given event @name. The event id is guaranteed not to change
* during the event lifetime (that is, between its registration and
* unregistration), thus it may be cached intermediatelly. */
/* It returns the event id on success or a negative number upon failure
* (ie. there is no such event). */
int get_event_id(const char *name);
/* This looks up the events table and returns the name of a given event
* @id. */
/* It returns the event name on success (statically allocated, you are
* not permitted to modify it) or NULL upon failure (ie. there is no
* such event). */
char *get_event_name(int id);
#define set_event_id(event, name) \
do { \
if (event == EVENT_NONE) \
event = get_event_id(name); \
} while (0)
/*** The events generator */
void trigger_event(int id, ...);
void trigger_event_name(const char *name, ...);
/*** The very events subsystem itself */
void init_event(void);
void done_event(void);
#ifdef __cplusplus
}
#endif
#endif