diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/narrative_window.c | 1 | ||||
-rw-r--r-- | src/sc_interp.c | 84 |
2 files changed, 84 insertions, 1 deletions
diff --git a/src/narrative_window.c b/src/narrative_window.c index da1d8f1..55d1961 100644 --- a/src/narrative_window.c +++ b/src/narrative_window.c @@ -238,6 +238,7 @@ NarrativeWindow *narrative_window_new(struct presentation *p, GApplication *app) stylesheets[2] = NULL; nw->sceditor = sc_editor_new(nw->p->scblocks, stylesheets); cbl = sc_callback_list_new(); + sc_callback_list_add_callback(cbl, "sthumb", render_thumbnail); sc_editor_set_callbacks(nw->sceditor, cbl); toolbar = gtk_toolbar_new(); diff --git a/src/sc_interp.c b/src/sc_interp.c index bed8fa2..40ab5ea 100644 --- a/src/sc_interp.c +++ b/src/sc_interp.c @@ -75,32 +75,113 @@ struct _scinterp struct sc_state *state; int j; /* Index of the current state */ int max_state; + + SCCallbackList *cbl; +}; + +typedef cairo_surface_t *(*SCCallbackFunc)(SCBlock *bl, void *); + +struct _sccallbacklist +{ + int n_callbacks; + int max_callbacks; + char **names; + SCCallbackFunc *funcs; }; SCCallbackList *sc_callback_list_new() { + SCCallbackList *cbl; + + cbl = malloc(sizeof(struct _sccallbacklist)); + if ( cbl == NULL ) return NULL; + + cbl->names = calloc(8, sizeof(char *)); + if ( cbl->names == NULL ) return NULL; + + cbl->funcs = calloc(8, sizeof(cbl->funcs[0])); + if ( cbl->funcs == NULL ) return NULL; + + cbl->max_callbacks = 8; + cbl->n_callbacks = 0; + + return cbl; } void sc_callback_list_free(SCCallbackList *cbl) { + int i; + + if ( cbl == NULL ) return; + + for ( i=0; i<cbl->n_callbacks; i++ ) { + free(cbl->names[i]); + } + + free(cbl->names); + free(cbl->funcs); + free(cbl); } void sc_callback_list_add_callback(SCCallbackList *cbl, const char *name, - cairo_surface_t *(*func)(SCBlock *bl, void *p)) + SCCallbackFunc func) { + if ( cbl->n_callbacks == cbl->max_callbacks ) { + + SCCallbackFunc *funcs_new; + char **names_new; + int mcn = cbl->max_callbacks + 8; + + names_new = realloc(cbl->names, mcn*sizeof(char *)); + funcs_new = realloc(cbl->funcs, mcn*sizeof(SCCallbackFunc)); + + if ( (names_new == NULL) || (funcs_new == NULL) ) { + fprintf(stderr, "Failed to grow callback list\n"); + return; + } + + cbl->names = names_new; + cbl->funcs = funcs_new; + cbl->max_callbacks = mcn; + + } + + cbl->names[cbl->n_callbacks] = strdup(name); + cbl->funcs[cbl->n_callbacks] = func; + cbl->n_callbacks++; } void sc_interp_set_callbacks(SCInterpreter *scin, SCCallbackList *cbl) { + if ( scin->cbl != NULL ) { + fprintf(stderr, "WARNING: Interpreter already has a callback " + "list.\n"); + } + scin->cbl = cbl; } static void do_callback(SCInterpreter *scin, const char *name) { + int i; + SCCallbackList *cbl = scin->cbl; + + if ( cbl == NULL ) { + fprintf(stderr, "No callback list.\n"); + return; + } + + for ( i=0; i<cbl->n_callbacks; i++ ) { + if ( strcmp(cbl->names[i], name) != 0 ) continue; + cbl->funcs[i](NULL, NULL); + return; + } + + fprintf(stderr, "Unknown callback '%s'\n", name); } @@ -391,6 +472,7 @@ SCInterpreter *sc_interp_new(PangoContext *pc, struct frame *top) scin->pc = pc; scin->s_constants = NULL; scin->p_constants = NULL; + scin->cbl = NULL; st = &scin->state[0]; st->n_macros = 0; |