From: ellson Date: Tue, 1 Aug 2006 21:19:59 +0000 (+0000) Subject: add an initialize() entry point for device plugins that we can use to: X-Git-Tag: LAST_LIBGRAPH~32^2~6012 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f36ac56be64861f24e3bf6519aab7c34135ae45a;p=graphviz add an initialize() entry point for device plugins that we can use to: - get dpi info from real screen device - open files for a filio device --- diff --git a/lib/common/emit.c b/lib/common/emit.c index 331348866..b26b03879 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -1830,9 +1830,14 @@ static void init_job_margin(GVJ_t *job) static void init_job_dpi(GVJ_t *job, graph_t *g) { + GVJ_t *firstjob = job->gvc->active_jobs; + if (GD_drawing(g)->dpi != 0) { job->dpi.x = job->dpi.y = (double)(GD_drawing(g)->dpi); } + else if (firstjob->device_sets_dpi) { + job->dpi = firstjob->device_dpi; /* some devices set dpi in initialize() */ + } else { /* set default margins depending on format */ switch (job->output_lang) { @@ -1910,8 +1915,6 @@ static void setup_view(GVJ_t * job, graph_t * g) double sx, sy; /* half width, half height in graph-units */ /* compute width,height in device units */ - /* FIXME - width/height also calculated in xlib finalize() using the same formula - * to get initial windows size. Should be done in one place only. */ job->width = ROUND((job->view.x + 2 * job->margin.x) * job->dpi.x / POINTS_PER_INCH); job->height = ROUND((job->view.y + 2 * job->margin.y) * job->dpi.y / POINTS_PER_INCH); @@ -2710,7 +2713,7 @@ extern gvdevice_callbacks_t gvdevice_callbacks; int gvRenderJobs (GVC_t * gvc, graph_t * g) { - GVJ_t *job, *prev_job, *active_job; + GVJ_t *job, *prevjob, *firstjob; if (!GD_drawing(g)) { agerr (AGERR, "Layout was not done. Missing layout plugins? \n"); @@ -2723,7 +2726,7 @@ int gvRenderJobs (GVC_t * gvc, graph_t * g) gvc->keybindings = gvevent_key_binding; gvc->numkeys = gvevent_key_binding_size; - prev_job = NULL; + prevjob = NULL; for (job = gvjobs_first(gvc); job; job = gvjobs_next(gvc)) { if (gvc->gvg) { job->input_filename = gvc->gvg->input_filename; @@ -2744,16 +2747,17 @@ int gvRenderJobs (GVC_t * gvc, graph_t * g) } /* if we already have an active job list and the device doesn't support mutiple output files, or we are about to write to a different output device */ - if ((active_job = gvc->active_jobs) - && (!(active_job->flags & GVRENDER_DOES_MULTIGRAPH_OUTPUT_FILES) - || (strcmp(job->output_langname,active_job->output_langname)))) { + firstjob = gvc->active_jobs; + if (firstjob + && (!(firstjob->flags & GVRENDER_DOES_MULTIGRAPH_OUTPUT_FILES) + || (strcmp(job->output_langname,firstjob->output_langname)))) { - gvrender_end_job(active_job); - gvdevice_finalize(gvc); /* finalize previous jobs */ + gvrender_end_job(firstjob); + gvdevice_finalize(firstjob); /* finalize previous jobs */ gvc->active_jobs = NULL; /* clear active list */ gvc->common.viewNum = 0; - prev_job = NULL; + prevjob = NULL; } if (!job->output_file) { /* if not yet opened */ @@ -2765,12 +2769,14 @@ int gvRenderJobs (GVC_t * gvc, graph_t * g) job->output_file = stdout; } - if (prev_job) - prev_job->next_active = job; /* insert job in active list */ - else + if (prevjob) { + prevjob->next_active = job; /* insert job in active list */ + } + else { gvc->active_jobs = job; /* first job of new list */ + gvdevice_initialize(job); + } job->next_active = NULL; /* terminate active list */ - prev_job = job; job->callbacks = &gvdevice_callbacks; @@ -2779,6 +2785,7 @@ int gvRenderJobs (GVC_t * gvc, graph_t * g) /* the last job, after all input graphs are processed, * is finalized from gvFreeContext() */ + prevjob = job; } return 0; } diff --git a/lib/gvc/gvc.c b/lib/gvc/gvc.c index 3a1d1e136..d0cac5361 100644 --- a/lib/gvc/gvc.c +++ b/lib/gvc/gvc.c @@ -87,7 +87,8 @@ int gvLayout(GVC_t *gvc, graph_t *g, char *engine) int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out) { int rc; - GVJ_t *job; + GVJ_t *job = gvc->job; + GVJ_t *firstjob = gvc->active_jobs; g = g->root; @@ -99,7 +100,6 @@ int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out) return -1; } - job = gvc->job; job->output_lang = gvrender_select(job, job->output_langname); if (!GD_drawing(g) && job->output_lang != CANONICAL_DOT) { fprintf(stderr, "Layout was not done\n"); @@ -107,8 +107,8 @@ int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out) } job->output_file = out; gvRenderJobs(gvc, g); - if (gvc->active_jobs) - gvdevice_finalize(gvc); + if (firstjob) + gvdevice_finalize(firstjob); gvjobs_delete(gvc); return 0; @@ -118,7 +118,8 @@ int gvRender(GVC_t *gvc, graph_t *g, char *format, FILE *out) int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename) { int rc; - GVJ_t *job; + GVJ_t *job = gvc->job; + GVJ_t *firstjob = gvc->active_jobs; g = g->root; @@ -129,7 +130,6 @@ int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename) return -1; } - job = gvc->job; job->output_lang = gvrender_select(job, job->output_langname); if (!GD_drawing(g) && job->output_lang != CANONICAL_DOT) { fprintf(stderr, "Layout was not done\n"); @@ -137,8 +137,8 @@ int gvRenderFilename(GVC_t *gvc, graph_t *g, char *format, char *filename) } gvjobs_output_filename(gvc, filename); gvRenderJobs(gvc, g); - if (gvc->active_jobs) - gvdevice_finalize(gvc); + if (firstjob) + gvdevice_finalize(firstjob); gvjobs_delete(gvc); return 0; diff --git a/lib/gvc/gvcjob.h b/lib/gvc/gvcjob.h index 65ee90fa3..9249617c9 100644 --- a/lib/gvc/gvcjob.h +++ b/lib/gvc/gvcjob.h @@ -226,6 +226,11 @@ extern "C" { gvplugin_active_device_t device; gvplugin_active_loadimage_t loadimage; gvdevice_callbacks_t *callbacks; + pointf device_dpi; + bool device_sets_dpi; + + void *display; + int screen; void *surface; /* gd or cairo surface */ bool external_surface; /* surface belongs to caller */ diff --git a/lib/gvc/gvcontext.c b/lib/gvc/gvcontext.c index bfcc1c0b5..56aef5ee6 100644 --- a/lib/gvc/gvcontext.c +++ b/lib/gvc/gvcontext.c @@ -61,10 +61,11 @@ GVC_t *gvNEWcontext(char **info, char *user) int gvFreeContext(GVC_t * gvc) { GVG_t *gvg, *gvg_next; + GVJ_t *firstjob; - if (gvc->active_jobs) { - gvrender_end_job(gvc->active_jobs); - gvdevice_finalize(gvc); + if ((firstjob = gvc->active_jobs)) { + gvrender_end_job(firstjob); + gvdevice_finalize(firstjob); } emit_once_reset(); gvg_next = gvc->gvgs; diff --git a/lib/gvc/gvcproc.h b/lib/gvc/gvcproc.h index a4ae709cf..5d49d2540 100644 --- a/lib/gvc/gvcproc.h +++ b/lib/gvc/gvcproc.h @@ -68,10 +68,8 @@ extern "C" { /* device */ - extern void gvdevice_initialize(GVC_t * gvc); - extern void gvdevice_finalize(GVC_t * gvc); - extern void gvdevice_begin_job(GVJ_t * job); - extern void gvdevice_end_job(GVJ_t * job); + extern void gvdevice_initialize(GVJ_t * job); + extern void gvdevice_finalize(GVJ_t * job); /* render */ diff --git a/lib/gvc/gvdevice.c b/lib/gvc/gvdevice.c index d447744ad..84d6c863a 100644 --- a/lib/gvc/gvdevice.c +++ b/lib/gvc/gvdevice.c @@ -28,15 +28,15 @@ #include "const.h" #include "gvplugin_device.h" +#include "gvcjob.h" #include "gvcint.h" #include "gvcproc.h" #if 0 /* This code is not used - see gvrender_select() in gvrender.c */ -int gvdevice_select(GVJ_t * job, char *str) +int gvdevice_select(GVC_t * gvc, char *str) { - GVC_t *gvc = job->gvc; gvplugin_available_t *plugin; gvplugin_installed_t *typeptr; #ifdef WITH_CODEGENS @@ -48,15 +48,15 @@ int gvdevice_select(GVJ_t * job, char *str) #ifdef WITH_CODEGENS if (strcmp(plugin->packagename, "cg") == 0) { cg_info = (codegen_info_t *) (plugin->typeptr); - job->codegen = cg_info->cg; + gvc->codegen = cg_info->cg; return cg_info->id; } else { #endif typeptr = plugin->typeptr; - job->device.engine = (gvdevice_engine_t *) (typeptr->engine); - job->device.features = + gvc->device.engine = (gvdevice_engine_t *) (typeptr->engine); + gvc->device.features = (gvdevice_features_t *) (typeptr->features); - job->device.id = typeptr->id; + gvc->device.id = typeptr->id; return GVRENDER_PLUGIN; #ifdef WITH_CODEGENS } @@ -65,31 +65,42 @@ int gvdevice_select(GVJ_t * job, char *str) return NO_SUPPORT; } -int gvdevice_features(GVJ_t * job) +int gvdevice_features(GVC_t * gvc) { - gvdevice_engine_t *gvde = job->device.engine; + gvdevice_engine_t *gvde = gvc->device.engine; int features = 0; if (gvde) - features = job->device.features->flags; + features = gvc->device.features->flags; return features; } #endif -void gvdevice_finalize(GVC_t * gvc) +void gvdevice_initialize(GVJ_t * firstjob) { - GVJ_t *active_job = gvc->active_jobs; - gvdevice_engine_t *gvde = active_job->device.engine; + gvdevice_engine_t *gvde = firstjob->device.engine; + + if (gvde) { + if (gvde->initialize) { + gvde->initialize(firstjob); + } + } +} + +void gvdevice_finalize(GVJ_t * firstjob) +{ + gvdevice_engine_t *gvde = firstjob->device.engine; + GVJ_t *job; if (gvde) { if (gvde->finalize) { - gvde->finalize(active_job); + gvde->finalize(firstjob); } } #ifdef WITH_CODEGENS else { - codegen_t *cg = active_job->codegen; + codegen_t *cg = firstjob->codegen; if (cg && cg->reset) cg->reset(); @@ -97,14 +108,13 @@ void gvdevice_finalize(GVC_t * gvc) #endif /* FIXME - file output should be its own device */ - while(active_job) { - if (active_job->output_filename - && active_job->output_file != stdout - && ! active_job->external_surface) { - fclose(active_job->output_file); - active_job->output_file = NULL; - active_job->output_filename = NULL; + for (job = firstjob; job; job = job->next_active) { + if (job->output_filename + && job->output_file != stdout + && ! job->external_surface) { + fclose(job->output_file); + job->output_file = NULL; + job->output_filename = NULL; } - active_job = active_job->next_active; } } diff --git a/lib/gvc/gvplugin_device.h b/lib/gvc/gvplugin_device.h index d032d9ac5..cd03318dc 100644 --- a/lib/gvc/gvplugin_device.h +++ b/lib/gvc/gvplugin_device.h @@ -26,6 +26,7 @@ extern "C" { #endif struct gvdevice_engine_s { + void (*initialize) (GVJ_t * firstjob); void (*finalize) (GVJ_t * firstjob); }; diff --git a/lib/gvc/gvrender.c b/lib/gvc/gvrender.c index b4e657400..aeb924502 100644 --- a/lib/gvc/gvrender.c +++ b/lib/gvc/gvrender.c @@ -70,20 +70,23 @@ int gvrender_select(GVJ_t * job, char *str) #endif typeptr = plugin->typeptr; job->render.engine = (gvrender_engine_t *) (typeptr->engine); - job->render.features = - (gvrender_features_t *) (typeptr->features); + job->render.features = (gvrender_features_t *) (typeptr->features); job->render.id = typeptr->id; device = job->render.features->device; if (device) { plugin = gvplugin_load(gvc, API_device, device); - if (! plugin) + if (! plugin) { + job->device.engine = NULL; return NO_SUPPORT; /* FIXME - should differentiate no device from no renderer */ + } typeptr = plugin->typeptr; job->device.engine = (gvdevice_engine_t *) (typeptr->engine); - job->device.features = - (gvdevice_features_t *) (typeptr->features); + job->device.features = (gvdevice_features_t *) (typeptr->features); job->device.id = typeptr->id; } + else { + job->device.engine = NULL; + } return GVRENDER_PLUGIN; #ifdef WITH_CODEGENS } diff --git a/plugin/gtk/gvdevice_gtk.c b/plugin/gtk/gvdevice_gtk.c index 1b6b48cd3..d59376039 100644 --- a/plugin/gtk/gvdevice_gtk.c +++ b/plugin/gtk/gvdevice_gtk.c @@ -53,6 +53,10 @@ attr_value_edited_cb(GtkCellRendererText *renderer, gchar *pathStr, gchar *newTe gtk_tree_path_free(path); } +static void initialize_gtk(GVJ_t *firstjob) +{ +} + static void finalize_gtk(GVJ_t *firstjob) { GVJ_t *job; @@ -119,6 +123,7 @@ static void finalize_gtk(GVJ_t *firstjob) } static gvdevice_engine_t device_engine_gtk = { + initialize_gtk, finalize_gtk, }; diff --git a/plugin/xlib/gvdevice_xlib.c b/plugin/xlib/gvdevice_xlib.c index 4f2d9fe85..b0e7538f1 100644 --- a/plugin/xlib/gvdevice_xlib.c +++ b/plugin/xlib/gvdevice_xlib.c @@ -294,13 +294,6 @@ static void init_window(GVJ_t *job, Display *dpy, int scr) job->fit_mode = 0; job->needs_refresh = 1; - job->dpi.x = DisplayWidth(dpy, scr) * 25.4 / DisplayWidthMM(dpy, scr); - job->dpi.y = DisplayHeight(dpy, scr) * 25.4 / DisplayHeightMM(dpy, scr); - - /* compute initial width,height in device units */ - job->width = ROUND((job->view.x + 2 * job->margin.x) * job->dpi.x / POINTS_PER_INCH); - job->height = ROUND((job->view.y + 2 * job->margin.y) * job->dpi.y / POINTS_PER_INCH); - if (argb && (window->visual = find_argb_visual(dpy, scr))) { window->cmap = XCreateColormap(dpy, RootWindow(dpy, scr), window->visual, AllocNone); @@ -451,15 +444,52 @@ static int handle_file_events(GVJ_t *job, int inotify_fd) } #endif -static void finalize(GVJ_t *firstjob) +static void initialize_xlib(GVJ_t *firstjob) { - GVJ_t *job; Display *dpy; - int i, scr, inotify_fd=0, xlib_fd, ret, events; - fd_set rfds; - const char *display_name = NULL; KeySym keysym; KeyCode *keycodes; + const char *display_name = NULL; + int i, scr; + + dpy = XOpenDisplay(display_name); + if (dpy == NULL) { + fprintf(stderr, "Failed to open XLIB display: %s\n", + XDisplayName(NULL)); + return; + } + scr = DefaultScreen(dpy); + + firstjob->display = (void*)dpy; + firstjob->screen = scr; + + keycodes = (KeyCode *)malloc(firstjob->numkeys * sizeof(KeyCode)); + if (keycodes == NULL) { + fprintf(stderr, "Failed to malloc %d*KeyCode\n", firstjob->numkeys); + return; + } + for (i = 0; i < firstjob->numkeys; i++) { + keysym = XStringToKeysym(firstjob->keybindings[i].keystring); + if (keysym == NoSymbol) + fprintf(stderr, "ERROR: No keysym for \"%s\"\n", + firstjob->keybindings[i].keystring); + else + keycodes[i] = XKeysymToKeycode(dpy, keysym); + } + firstjob->keycodes = (void*)keycodes; + + firstjob->device_dpi.x = DisplayWidth(dpy, scr) * 25.4 / DisplayWidthMM(dpy, scr); + firstjob->device_dpi.y = DisplayHeight(dpy, scr) * 25.4 / DisplayHeightMM(dpy, scr); + firstjob->device_sets_dpi = true; +} + +static void finalize_xlib(GVJ_t *firstjob) +{ + GVJ_t *job; + Display *dpy; + KeyCode *keycodes; + int scr, inotify_fd=0, xlib_fd, ret, events; + fd_set rfds; struct timeval timeout; #ifdef HAVE_SYS_INOTIFY_H int wd=0; @@ -467,6 +497,9 @@ static void finalize(GVJ_t *firstjob) static char *dir; char *p, *cwd = NULL; + dpy = (Display *)(firstjob->display); + scr = firstjob->screen; + inotify_fd = inotify_init(); if (inotify_fd < 0) { fprintf(stderr,"inotify_init() failed\n"); @@ -497,29 +530,6 @@ static void finalize(GVJ_t *firstjob) } #endif - dpy = XOpenDisplay(display_name); - if (dpy == NULL) { - fprintf(stderr, "Failed to open XLIB display: %s\n", - XDisplayName(NULL)); - return; - } - scr = DefaultScreen(dpy); - - keycodes = (KeyCode *)malloc(firstjob->numkeys * sizeof(KeyCode)); - if (keycodes == NULL) { - fprintf(stderr, "Failed to malloc %d*KeyCode\n", firstjob->numkeys); - return; - } - for (i = 0; i < firstjob->numkeys; i++) { - keysym = XStringToKeysym(firstjob->keybindings[i].keystring); - if (keysym == NoSymbol) - fprintf(stderr, "ERROR: No keysym for \"%s\"\n", - firstjob->keybindings[i].keystring); - else - keycodes[i] = XKeysymToKeycode(dpy, keysym); - } - firstjob->keycodes = (void*)keycodes; - for (job = firstjob; job; job = job->next_active) init_window(job, dpy, scr); @@ -573,7 +583,8 @@ static void finalize(GVJ_t *firstjob) } static gvdevice_engine_t device_engine_xlib = { - finalize, + initialize_xlib, + finalize_xlib, }; gvplugin_installed_t gvdevice_types_xlib[] = {