https://bitbucket.org/daniel_fort/magic-lantern
Raw File
Tip revision: 4643aff8322697b4737d5ebe9dc1d89012c758b6 authored by a1ex on 19 June 2016, 18:36:52 UTC
Close branch McGv/guicommonc-edited-online-with-bitbucket--1440276480831.
Tip revision: 4643aff
module.h
#ifndef _module_h_
#define _module_h_

#include <stdint.h>

#define MODULE_PATH                   "ML/MODULES/"

/* module info structures */
#define MODULE_INFO_PREFIX            __module_info_
#define MODULE_STRINGS_PREFIX         __module_strings_
#define MODULE_PROPHANDLERS_PREFIX    __module_prophandlers_
#define MODULE_CBR_PREFIX             __module_cbr_
#define MODULE_CONFIG_PREFIX          __module_config_
#define MODULE_PROPHANDLER_PREFIX     __module_prophandler_

#define MODULE_STRINGS_SECTION        __attribute__ ((section(".module_strings")))

#define MODULE_MAGIC                  0x5A
#define STR(x)                        STR_(x)
#define STR_(x)                       #x

#define MODULE_COUNT_MAX              32
#define MODULE_NAME_LENGTH            8
#define MODULE_FILENAME_LENGTH        31    /* A:/ML/MODULES/8_3_name.mo */
#define MODULE_STATUS_LENGTH          7     /* longest is FileErr */
#define MODULE_LONG_STATUS_LENGTH     63

/* some callbacks that may be needed by modules. more to come. ideas? needs? */
#define CBR_PRE_SHOOT                 1 /* called before image is taken */
#define CBR_POST_SHOOT                2 /* called after image is taken */
#define CBR_SHOOT_TASK                3 /* called periodically from shoot task */
#define CBR_DISPLAY_FILTER            4
/**
 * Display filters (things that alter the LiveView image)
 * 
 * - ctx=0: should return 1 if the display filter mode should be enabled, 0 if not
 *          (but must not do any heavy processing!!!)
 * 
 * - else: ctx is a (struct display_filter_buffers *), see vram.h
 *         (contains src_buf and dst_buf)
 *         in this case, the cbr should paint the new image in dst_buf,
 *         usually by processing the data from src_buf
 *
 * - note: some cameras do not support display filters; in this case, this CBR will not be called
 */
#define CBR_SECONDS_CLOCK             5 /* called every second */
#define CBR_VSYNC                     6 /* called for every LiveView frame; can do display tricks; must not do any heavy processing!!! */
#define CBR_KEYPRESS                  7 /* when a key was pressed, this cbr gets the translated key as ctx */
#define CBR_KEYPRESS_RAW              8 /* when a key was pressed, this cbr gets the raw (struct event *) as ctx */
#define CBR_VSYNC_SETPARAM            9 /* called from every LiveView frame; can change FRAME_ISO, FRAME_SHUTTER_TIMER, just like for HDR video */

#define CBR_CUSTOM_PICTURE_TAKING    11 /* special types of picture taking (e.g. silent pics); so intervalometer and other photo taking routines should use that instead of regular pics */
#define CBR_INTERVALOMETER           12 /* called after a picture is taken with the intervalometer */

/* return values from CBRs */
#define CBR_RET_CONTINUE              0             /* keep calling other CBRs of the same type */
#define CBR_RET_STOP                  1             /* stop calling other CBRs */
#define CBR_RET_ERROR                 0xFFFFFFFF    /* something's wong */

/* portable key codes. intentionally defines to make numbers hardcoded so changed order wont change the integer number */
#define MODULE_KEY_PRESS_HALFSHUTTER       ( 1)
#define MODULE_KEY_UNPRESS_HALFSHUTTER     ( 2)
#define MODULE_KEY_PRESS_FULLSHUTTER       ( 3)
#define MODULE_KEY_UNPRESS_FULLSHUTTER     ( 4)
#define MODULE_KEY_WHEEL_UP                ( 5)
#define MODULE_KEY_WHEEL_DOWN              ( 6)
#define MODULE_KEY_WHEEL_LEFT              ( 7)
#define MODULE_KEY_WHEEL_RIGHT             ( 8)
#define MODULE_KEY_PRESS_SET               ( 9)
#define MODULE_KEY_UNPRESS_SET             (10)
#define MODULE_KEY_JOY_CENTER              (11)
#define MODULE_KEY_PRESS_UP                (12)
#define MODULE_KEY_PRESS_UP_RIGHT          (13)
#define MODULE_KEY_PRESS_UP_LEFT           (14)
#define MODULE_KEY_PRESS_RIGHT             (15)
#define MODULE_KEY_PRESS_LEFT              (16)
#define MODULE_KEY_PRESS_DOWN_RIGHT        (17)
#define MODULE_KEY_PRESS_DOWN_LEFT         (18)
#define MODULE_KEY_PRESS_DOWN              (19)
#define MODULE_KEY_UNPRESS_UDLR            (20)
#define MODULE_KEY_PRESS_ZOOMIN            (21)     
#define MODULE_KEY_MENU                    (22)
#define MODULE_KEY_INFO                    (23)
#define MODULE_KEY_PLAY                    (24)
#define MODULE_KEY_TRASH                   (25)
#define MODULE_KEY_RATE                    (26)
#define MODULE_KEY_REC                     (27)
#define MODULE_KEY_LV                      (28)
#define MODULE_KEY_Q                       (29)
#define MODULE_KEY_PICSTYLE                (30)
#define MODULE_KEY_PRESS_FLASH_MOVIE       (31)
#define MODULE_KEY_UNPRESS_FLASH_MOVIE     (32)
#define MODULE_KEY_PRESS_DP                (33)
#define MODULE_KEY_UNPRESS_DP              (34)
#define MODULE_KEY_TOUCH_1_FINGER          (35)
#define MODULE_KEY_UNTOUCH_1_FINGER        (36)
#define MODULE_KEY_TOUCH_2_FINGER          (37)
#define MODULE_KEY_UNTOUCH_2_FINGER        (38)


#define MODULE_KEY_CANON     0
#define MODULE_KEY_PORTABLE  1


/* update major if older modules will *not* be compatible */
#define MODULE_MAJOR 6
/* update minor if older modules will be compatible, but newer module will not run on older magic lantern versions */
#define MODULE_MINOR 0
/* update patch if nothing regarding to compatibility changes */
#define MODULE_PATCH 0

/* module description that every module should deliver - optional.
   if not supplied, only the symbols are visible to other plugins.
   this might be useful for libraries.
*/
typedef struct
{
    /* major determines the generic compatibilty, minor is backward compatible (e.g. new hooks) */
    const unsigned char api_magic;
    const unsigned char api_major;
    const unsigned char api_minor;
    const unsigned char api_patch;

    /* the plugin's name and init/deinit functions */
    const char *name;
    const char *long_name;
    unsigned int (*init) ();
    unsigned int (*deinit) ();
} module_info_t;

/* this struct supplies additional information like license, author etc - optional */
typedef struct
{
    const char *name;
    const char *value;
} module_strpair_t;

/* this struct supplies a list of callback routines to call - optional */
typedef struct
{
    const char *name;
    const char *symbol;
    unsigned int type;
    unsigned int (*handler) (unsigned int);
    unsigned int ctx;
} module_cbr_t;

/* this struct supplies a list of config entries liek CONFIG_INT - optional */
typedef struct
{
    const char *name;
    const struct config_var *ref;
} module_config_t;

/* this struct supplies additional information like license, author etc - optional */
typedef struct
{
    const char *name;
    void (*handler)(unsigned int property, void * priv, uint32_t * addr, unsigned int len);
    const unsigned int property;
    const unsigned int property_length;
} module_prophandler_t;


/* index of all loaded modules */
typedef struct
{
    char name[MODULE_NAME_LENGTH+1];
    char filename[MODULE_FILENAME_LENGTH+1];
    char long_filename[MODULE_FILENAME_LENGTH+1];
    char status[MODULE_STATUS_LENGTH+1];
    char long_status[MODULE_LONG_STATUS_LENGTH+1];
    module_info_t *info;
    module_strpair_t *strings;
    module_prophandler_t **prop_handlers;
    module_cbr_t *cbr;
    module_config_t *config;
    int valid;
    int enabled;
    int error;
} module_entry_t;


#define MODULE_INFO_START()                                     MODULE_INFO_START_(MODULE_INFO_PREFIX,MODULE_NAME)
#define MODULE_INFO_START_(prefix,modname)                      MODULE_INFO_START__(prefix,modname)
#define MODULE_INFO_START__(prefix,modname)                     module_info_t prefix##modname = \
                                                                {\
                                                                    .api_magic = MODULE_MAGIC, \
                                                                    .api_major = MODULE_MAJOR, \
                                                                    .api_minor = MODULE_MINOR, \
                                                                    .api_patch = MODULE_PATCH, \
                                                                    .name = #modname,
#define MODULE_INIT(func)                                           .init = &func,
#define MODULE_DEINIT(func)                                         .deinit = &func,
#define MODULE_LONGNAME(name)                                       .long_name = name,
#define MODULE_CB_SHOOT_TASK(func)                                  .cb_shoot_task = &func,
#define MODULE_CB_PRE_SHOOT(func)                                   .cb_pre_shoot = &func,
#define MODULE_CB_POST_SHOOT(func)                                  .cb_post_shoot = &func,
#define MODULE_INFO_END()                                       };
                                                                
#define MODULE_STRINGS_START()                                  MODULE_STRINGS_START_(MODULE_STRINGS_PREFIX,MODULE_NAME)
#define MODULE_STRINGS_START_(prefix,modname)                   MODULE_STRINGS_START__(prefix,modname)
#define MODULE_STRINGS_START__(prefix,modname)                  module_strpair_t prefix##modname[] MODULE_STRINGS_SECTION = {
#define MODULE_STRING(field,value)                                  { field, value },
#define MODULE_STRINGS_END()                                        { (const char *)0, (const char *)0 }\
                                                                };                                                                
#define MODULE_CBRS_START()                                     MODULE_CBRS_START_(MODULE_CBR_PREFIX,MODULE_NAME)
#define MODULE_CBRS_START_(prefix,modname)                      MODULE_CBRS_START__(prefix,modname)
#define MODULE_CBRS_START__(prefix,modname)                     module_cbr_t prefix##modname[] = {
#define MODULE_CBR(cb_type,cbr,context)                         { .name = #cb_type, .symbol = #cbr, .type = cb_type, .handler = cbr, .ctx = context },
#define MODULE_CBRS_END()                                           { (void *)0, (void *)0, 0, (void *)0, 0 }\
                                                                };
                                                            
#define MODULE_CONFIGS_START()                                  MODULE_CONFIGS_START_(MODULE_CONFIG_PREFIX,MODULE_NAME)
#define MODULE_CONFIGS_START_(prefix,modname)                   MODULE_CONFIGS_START__(prefix,modname)
#define MODULE_CONFIGS_START__(prefix,modname)                  module_config_t prefix##modname[] = {
#define MODULE_CONFIG(cfg)                                      { .name = #cfg, .ref = &__config_##cfg },
#define MODULE_CONFIGS_END()                                        { (void *)0, (void *)0 }\
                                                                };
                                                                
#define MODULE_PROPHANDLERS_START()                             MODULE_PROPHANDLERS_START_(MODULE_PROPHANDLERS_PREFIX,MODULE_NAME,MODULE_PROPHANDLER_PREFIX)
#define MODULE_PROPHANDLERS_START_(prefix,modname,ph_prefix)    MODULE_PROPHANDLERS_START__(prefix,modname,ph_prefix)
#define MODULE_PROPHANDLERS_START__(prefix,modname,ph_prefix)   module_prophandler_t *prefix##modname[] = {
#define MODULE_PROPHANDLER(id)                                      MODULE_PROPHANDLER_(MODULE_PROPHANDLERS_PREFIX,MODULE_NAME,MODULE_PROPHANDLER_PREFIX,id)
#define MODULE_PROPHANDLER_(prefix,modname,ph_prefix,id)            MODULE_PROPHANDLER__(prefix,modname,ph_prefix,id)
#define MODULE_PROPHANDLER__(prefix,modname,ph_prefix,id)           &ph_prefix##modname##_##id##_block,
#define MODULE_PROPHANDLERS_END()                                   NULL\
                                                                };

#if defined(MODULE)
#define PROP_HANDLER(id)                                        MODULE_PROP_ENTRY_(MODULE_PROPHANDLER_PREFIX,MODULE_NAME, id, #id)
#define MODULE_PROP_ENTRY_(prefix,modname,id,idstr)             MODULE_PROP_ENTRY__(prefix,modname,id,idstr)
#define MODULE_PROP_ENTRY__(prefix,modname,id,idstr)            void prefix##modname##_##id(unsigned int, void *, uint32_t *, unsigned int);\
                                                                module_prophandler_t prefix##modname##_##id##_block = { \
                                                                    .name            = idstr, \
                                                                    .handler         = &prefix##modname##_##id, \
                                                                    .property        = id, \
                                                                    .property_length = 0, \
                                                                }; \
                                                                void prefix##modname##_##id( \
                                                                        unsigned int property, \
                                                                        void *       token, \
                                                                        uint32_t *   buf, \
                                                                        unsigned int len \
                                                                )

#define PROP_INT(id,name) \
volatile uint32_t name; \
PROP_HANDLER(id) { \
        name = buf[0]; \
}

#endif


/* load all available modules. will be used on magic lantern boot */
void module_load_all(void);
void module_unload_all(void);

/* explicitely load a standalone module. this is comparable to an executable */
void *module_load(char *filename);
int module_exec(void *module, char *symbol, int count, ...);
int module_unload(void *module);
unsigned int module_get_symbol(void *module, char *symbol);

/* execute all callback routines of given type. maybe it will get extended to support varargs */
int module_exec_cbr(unsigned int type);

int module_set_config_cbr(unsigned int (*load_func)(char *, module_entry_t *), unsigned int (save_func)(char *, module_entry_t *));
int module_unset_config_cbr();

/* lookup a pointer in the list of config variables */
struct config_var* module_config_var_lookup(int* ptr);

/* lookup a config variable by name */
struct config_var * module_get_config_var(const char * name);

/* called from config backend */
void module_save_configs();

/* defined in config.c */
unsigned int module_config_load(char *filename, module_entry_t *module);
unsigned int module_config_save(char *filename, module_entry_t *module);

int module_send_keypress(int module_key);

/* display filter interface for modules */
int module_display_filter_enabled();
int module_display_filter_update();

struct module_symbol_entry
{
    const char * name;
    void** address;
};

/* 
 * For module routines that may be called from core:
 *
 * usage:
 * static void(*auto_ettr_intervalometer_wait)(void) = MODULE_FUNCTION(auto_ettr_intervalometer_wait);
 * (if that module is not available, it simply calls ret_0)
 * 
 * or, a little more advanced:
 * static void(*foobar)(int, int) = MODULE_SYMBOL(do_foobar, default_function)
 * 
 * All module symbols are updated after modules are loaded.
 * 
 * You **MUST** declare these symbols static.
 * If you don't, the error will only be detected at runtime, if no modules are loaded.
 */

#define MODULE_SYMBOL(NAME, DEFAULT_ADDRESS) \
(void*)(DEFAULT_ADDRESS); \
static struct module_symbol_entry \
__attribute__((section(".module_symbols"))) \
__attribute__((used)) \
module_symbol_##NAME = { \
        .name           = #NAME, \
        .address        = (void*)&NAME, \
}     //.default_address = DEFAULT_ADDRESS, /* not used; can be useful for module unloading */

#define MODULE_FUNCTION(name) MODULE_SYMBOL(name, ret_0)

/* for camera-specific tricks in modules */
/* e.g. if (is_camera("5D3", "1.2.3")) { adtg_write_addr = 0x1234 } */
/* see propvalues.c */
extern int is_camera(const char * model, const char * firmware);

#ifdef MODULE
#include "module_strings.h"
#endif

#endif
back to top