summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorRobin Watts <Robin.Watts@artifex.com>2020-06-04 19:27:15 +0100
committerRobin Watts <Robin.Watts@artifex.com>2020-06-25 00:19:12 +0100
commit4438e3e5bc4dfc9e46fc86d86d912171ec582a4e (patch)
treec2cbc61774320346337f2311876f4bc9de46d011 /base
parent7e427246abb151cde9154783775acfaa776b502e (diff)
downloadghostpdl-4438e3e5bc4dfc9e46fc86d86d912171ec582a4e.tar.gz
Rework display device "DisplayHandle" passing.
Add gsapi_{,de}register_callout API. This allows integrators to register handlers for "callouts" from gs devices. The first example of such a callout is the display device. Previously, this has relied on the gsapi_set_display_callback API to pass a pointer to a structure into the core, from where it was hackily poked into the display device structure. Instead, we now have the display device "callout" to registered handlers to get the structure and the handle to use. The legacy API is maintained by the API level implementing a handler to return the display callback in response to the devices callout. The code to do the 'poking' of the display device has therefore been removed, and replaced by code that checks to see if an opened device needs reopening after init, if so, opens/closes it.
Diffstat (limited to 'base')
-rw-r--r--base/gsdevice.c6
-rw-r--r--base/gslibctx.c68
-rw-r--r--base/gslibctx.h16
-rw-r--r--base/gxdevcli.h3
-rw-r--r--base/gxdevsop.h9
5 files changed, 102 insertions, 0 deletions
diff --git a/base/gsdevice.c b/base/gsdevice.c
index cd9460374..ec0f79e58 100644
--- a/base/gsdevice.c
+++ b/base/gsdevice.c
@@ -1346,3 +1346,9 @@ bool gx_color_info_equal(const gx_device_color_info * p1, const gx_device_color_
return false;
return true;
}
+
+int gx_callout(gx_device *dev, int id, int size, void *data)
+{
+ return gs_lib_ctx_callout(dev->memory, dev->dname,
+ id, size, data);
+}
diff --git a/base/gslibctx.c b/base/gslibctx.c
index b2e046e06..35490b504 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -1179,3 +1179,71 @@ int gs_lib_ctx_get_args(gs_lib_ctx_t *ctx, const char * const **argv)
*argv = (const char * const *)core->argv;
return core->argc;
}
+
+int gs_lib_ctx_register_callout(gs_memory_t *mem, gs_callout_fn fn, void *arg)
+{
+ gs_lib_ctx_core_t *core;
+ gs_callout_list_t *entry;
+
+ if (mem == NULL || mem->gs_lib_ctx == NULL ||
+ mem->gs_lib_ctx->core == NULL || fn == NULL)
+ return 0;
+
+ core = mem->gs_lib_ctx->core;
+ entry = (gs_callout_list_t *)gs_alloc_bytes(mem->non_gc_memory,
+ sizeof(*entry),
+ "gs_callout_list_t");
+ if (entry == NULL)
+ return_error(gs_error_VMerror);
+ entry->next = core->callouts;
+ entry->callout = fn;
+ entry->handle = arg;
+ core->callouts = entry;
+
+ return 0;
+}
+
+void gs_lib_ctx_deregister_callout(gs_memory_t *mem, gs_callout_fn fn, void *arg)
+{
+ gs_lib_ctx_core_t *core;
+ gs_callout_list_t **entry;
+
+ if (mem == NULL || mem->gs_lib_ctx == NULL ||
+ mem->gs_lib_ctx->core == NULL || fn == NULL)
+ return;
+
+ core = mem->gs_lib_ctx->core;
+ entry = &core->callouts;
+ while (*entry) {
+ if ((*entry)->callout == fn && (*entry)->handle == arg) {
+ gs_callout_list_t *next = (*entry)->next;
+ gs_free_object(mem->non_gc_memory, *entry, "gs_callout_list_t");
+ *entry = next;
+ } else {
+ entry = &(*entry)->next;
+ }
+ }
+}
+
+int gs_lib_ctx_callout(gs_memory_t *mem, const char *dev_name,
+ int id, int size, void *data)
+{
+ gs_lib_ctx_core_t *core;
+ gs_callout_list_t *entry;
+
+ if (mem == NULL || mem->gs_lib_ctx == NULL || mem->gs_lib_ctx->core == NULL)
+ return -1;
+
+ core = mem->gs_lib_ctx->core;
+ entry = core->callouts;
+ while (entry) {
+ int code = entry->callout(mem->gs_lib_ctx->top_of_system,
+ entry->handle, dev_name, id, size, data);
+ if (code >= 0)
+ return code;
+ if (code != gs_error_unknownerror)
+ return code;
+ entry = entry->next;
+ }
+ return -1;
+}
diff --git a/base/gslibctx.h b/base/gslibctx.h
index f6ce40a32..173d2dc2a 100644
--- a/base/gslibctx.h
+++ b/base/gslibctx.h
@@ -81,6 +81,14 @@ typedef struct gs_fs_list_s {
struct gs_fs_list_s *next;
} gs_fs_list_t;
+typedef int (*gs_callout_fn)(void *, void *, const char *, int, int, void *);
+
+typedef struct gs_callout_list_s {
+ struct gs_callout_list_s *next;
+ gs_callout_fn callout;
+ void *handle;
+} gs_callout_list_t;
+
typedef struct {
void *monitor;
int refs;
@@ -118,6 +126,8 @@ typedef struct {
* all builds. */
void *cal_ctx;
+ gs_callout_list_t *callouts;
+
/* Stashed args */
int arg_max;
int argc;
@@ -194,6 +204,12 @@ void *gs_lib_ctx_get_cms_context( const gs_memory_t *mem );
void gs_lib_ctx_set_cms_context( const gs_memory_t *mem, void *cms_context );
int gs_lib_ctx_get_act_on_uel( const gs_memory_t *mem );
+int gs_lib_ctx_register_callout(gs_memory_t *mem, gs_callout_fn, void *arg);
+void gs_lib_ctx_deregister_callout(gs_memory_t *mem, gs_callout_fn, void *arg);
+int gs_lib_ctx_callout(gs_memory_t *mem, const char *dev_name,
+ int id, int size, void *data);
+
+
#ifndef GS_THREADSAFE
/* HACK to get at non garbage collection memory pointer
*
diff --git a/base/gxdevcli.h b/base/gxdevcli.h
index e7a054321..e7c3a78a4 100644
--- a/base/gxdevcli.h
+++ b/base/gxdevcli.h
@@ -1982,4 +1982,7 @@ void gx_device_dump(gx_device *dev, const char *text);
/* Compare color information structures */
bool gx_color_info_equal(const gx_device_color_info *p1, const gx_device_color_info *p2);
+/* Perform a callout to registered handlers from the device. */
+int gx_callout(gx_device *dev, int id, int size, void *data);
+
#endif /* gxdevcli_INCLUDED */
diff --git a/base/gxdevsop.h b/base/gxdevsop.h
index 3ba09fd2b..4c597de08 100644
--- a/base/gxdevsop.h
+++ b/base/gxdevsop.h
@@ -379,6 +379,15 @@ enum {
* 0 otherwise.
*/
gxdso_supports_alpha,
+ /* gxdso_reopen_after_init:
+ * data = NULL
+ * size = 0
+ * Returns 1 if the device should be closed/reopened after gs
+ * finishes initialisation (e.g. to give it a chance to fetch
+ * configuration from registered callout handlers),
+ * 0 otherwise.
+ */
+ gxdso_reopen_after_init,
/* Add new gxdso_ keys above this. */
gxdso_pattern__LAST
};