summaryrefslogtreecommitdiff
path: root/gs/src/gsnotify.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/gsnotify.c')
-rw-r--r--gs/src/gsnotify.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/gs/src/gsnotify.c b/gs/src/gsnotify.c
new file mode 100644
index 000000000..33b3b7d89
--- /dev/null
+++ b/gs/src/gsnotify.c
@@ -0,0 +1,115 @@
+/* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+ */
+
+
+/* Notification machinery implementation */
+#include "gx.h"
+#include "gserrors.h"
+#include "gsstruct.h"
+#include "gsnotify.h"
+
+/* GC descriptors */
+private_st_gs_notify_registration();
+public_st_gs_notify_list();
+
+/* Initialize a notification list. */
+void
+gs_notify_init(gs_notify_list_t *nlist, gs_memory_t *mem)
+{
+ nlist->first = 0;
+ nlist->memory = mem;
+}
+
+/* Register a client. */
+int
+gs_notify_register(gs_notify_list_t *nlist, gs_notify_proc_t proc,
+ void *proc_data)
+{
+ gs_notify_registration_t *nreg =
+ gs_alloc_struct(nlist->memory, gs_notify_registration_t,
+ &st_gs_notify_registration, "gs_notify_register");
+
+ if (nreg == 0)
+ return_error(gs_error_VMerror);
+ nreg->proc = proc;
+ nreg->proc_data = proc_data;
+ nreg->next = nlist->first;
+ nlist->first = nreg;
+ return 0;
+}
+
+/*
+ * Unregister a client. Return 1 if the client was registered, 0 if not.
+ * If proc_data is 0, unregister all registrations of that proc; otherwise,
+ * unregister only the registration of that procedure with that proc_data.
+ */
+int
+gs_notify_unregister(gs_notify_list_t *nlist, gs_notify_proc_t proc,
+ void *proc_data)
+{
+ gs_notify_registration_t **prev = &nlist->first;
+ gs_notify_registration_t *cur;
+ bool found = 0;
+
+ while ((cur = *prev) != 0)
+ if (cur->proc == proc &&
+ (proc_data == 0 || cur->proc_data == proc_data)
+ ) {
+ *prev = cur->next;
+ gs_free_object(nlist->memory, cur, "gs_notify_unregister");
+ found = 1;
+ } else
+ prev = &cur->next;
+ return found;
+}
+
+/*
+ * Notify the clients on a list. If an error occurs, return the first
+ * error code, but notify all clients regardless.
+ */
+int
+gs_notify_all(gs_notify_list_t *nlist, void *event_data)
+{
+ gs_notify_registration_t *cur;
+ gs_notify_registration_t *next;
+ int ecode = 0;
+
+ for (next = nlist->first; (cur = next) != 0;) {
+ int code;
+
+ next = cur->next;
+ code = cur->proc(cur->proc_data, event_data);
+ if (code < 0 && ecode == 0)
+ ecode = code;
+ }
+ return ecode;
+}
+
+/* Release a notification list. */
+void
+gs_notify_release(gs_notify_list_t *nlist)
+{
+ gs_memory_t *mem = nlist->memory;
+
+ while (nlist->first) {
+ gs_notify_registration_t *next = nlist->first->next;
+
+ gs_free_object(mem, nlist->first, "gs_notify_release");
+ nlist->first = next;
+ }
+}