]> granicus.if.org Git - graphviz/commitdiff
add an initialize() entry point for device plugins that we can use to:
authorellson <devnull@localhost>
Tue, 1 Aug 2006 21:19:59 +0000 (21:19 +0000)
committerellson <devnull@localhost>
Tue, 1 Aug 2006 21:19:59 +0000 (21:19 +0000)
- get dpi info from real screen device
- open files for a filio device

lib/common/emit.c
lib/gvc/gvc.c
lib/gvc/gvcjob.h
lib/gvc/gvcontext.c
lib/gvc/gvcproc.h
lib/gvc/gvdevice.c
lib/gvc/gvplugin_device.h
lib/gvc/gvrender.c
plugin/gtk/gvdevice_gtk.c
plugin/xlib/gvdevice_xlib.c

index 3313488660ad2b07e441e582dbb11e052f070cf8..b26b0387926251ec696b9978849f4641d8fcc96f 100644 (file)
@@ -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;
 }
index 3a1d1e136c63b6614369ea4bd992a15105deb76d..d0cac5361713cd46c9a41688f9c5989665f2e8a1 100644 (file)
@@ -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;
index 65ee90fa3a7d555055368642cde9b66f2f2832d1..9249617c9f8df6671ac4163aa44d29f22c9a4755 100644 (file)
@@ -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 */
index bfcc1c0b5a7a14243a0a9fc494175c87c7bad1e3..56aef5ee60a622e4c560096dfa75991b502d58a8 100644 (file)
@@ -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;
index a4ae709cf8214eae0f41c7862fd73a74545e550b..5d49d254070fcf8c1a1a80842fc386a4fd094940 100644 (file)
@@ -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 */
 
index d447744ad658c53b919e2100155716ad0febd894..84d6c863a9aaff9cdaeab935fd91e1d260bd278e 100644 (file)
 
 #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;
     }
 }
index d032d9ac5c5d1b5fd2ea403714aa02c50e4da5ec..cd03318dc253a582d8eb9f70b53e015dc74ef8b9 100644 (file)
@@ -26,6 +26,7 @@ extern "C" {
 #endif
 
     struct gvdevice_engine_s {
+       void (*initialize) (GVJ_t * firstjob);
        void (*finalize) (GVJ_t * firstjob);
     };
 
index b4e657400e2ac74f56de0f5c67f09a7b1d2fb32d..aeb924502e88aea278a8b10e5361cba21e64f4e7 100644 (file)
@@ -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
        }
index 1b6b48cd391b8842780746d4088c72476d68dfeb..d59376039dd577d246ecc34334505e47b20b147b 100644 (file)
@@ -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,
 };
 
index 4f2d9fe85654bd2e4dd51bb3eaaa564555dffd39..b0e7538f190aeee373b55589944c28dcd82698df 100644 (file)
@@ -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[] = {