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) {
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);
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");
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;
}
/* 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 */
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;
/* the last job, after all input graphs are processed,
* is finalized from gvFreeContext()
*/
+ prevjob = job;
}
return 0;
}
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;
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");
}
job->output_file = out;
gvRenderJobs(gvc, g);
- if (gvc->active_jobs)
- gvdevice_finalize(gvc);
+ if (firstjob)
+ gvdevice_finalize(firstjob);
gvjobs_delete(gvc);
return 0;
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;
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");
}
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;
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 */
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;
/* 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 */
#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
#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
}
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();
#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;
}
}
#endif
struct gvdevice_engine_s {
+ void (*initialize) (GVJ_t * firstjob);
void (*finalize) (GVJ_t * firstjob);
};
#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
}
gtk_tree_path_free(path);
}
+static void initialize_gtk(GVJ_t *firstjob)
+{
+}
+
static void finalize_gtk(GVJ_t *firstjob)
{
GVJ_t *job;
}
static gvdevice_engine_t device_engine_gtk = {
+ initialize_gtk,
finalize_gtk,
};
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);
}
#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;
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");
}
#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);
}
static gvdevice_engine_t device_engine_xlib = {
- finalize,
+ initialize_xlib,
+ finalize_xlib,
};
gvplugin_installed_t gvdevice_types_xlib[] = {