summaryrefslogtreecommitdiff
path: root/pdf
diff options
context:
space:
mode:
authorPaul Gardiner <paulg.artifex@glidos.net>2012-09-18 12:02:33 +0100
committerPaul Gardiner <paulg.artifex@glidos.net>2012-09-18 15:00:00 +0100
commit415ae3908a392363b2196ce8c0c913c78e2f0320 (patch)
tree3558eb4d6722991c15e225b2c15e3a977ccf1f6a /pdf
parente6ed164c3935160d3d42aa15017abe2863bbdaac (diff)
downloadmupdf-415ae3908a392363b2196ce8c0c913c78e2f0320.tar.xz
Forms: add event handling api and specifically support for javascript alert
Diffstat (limited to 'pdf')
-rw-r--r--pdf/mupdf-internal.h6
-rw-r--r--pdf/pdf_event.c34
-rw-r--r--pdf/pdf_js.c87
3 files changed, 127 insertions, 0 deletions
diff --git a/pdf/mupdf-internal.h b/pdf/mupdf-internal.h
index 1d1fd4e7..7fd287dd 100644
--- a/pdf/mupdf-internal.h
+++ b/pdf/mupdf-internal.h
@@ -228,6 +228,9 @@ struct pdf_document_s
pdf_js *js;
int recalculating;
int dirty;
+
+ fz_doc_event_cb *event_cb;
+ void *event_cb_data;
};
pdf_document *pdf_open_document_no_run(fz_context *ctx, const char *filename);
@@ -627,6 +630,9 @@ int pdf_choice_widget_options(pdf_document *doc, fz_widget *tw, char *opts[]);
int pdf_choice_widget_is_multiselect(pdf_document *doc, fz_widget *tw);
int pdf_choice_widget_value(pdf_document *doc, fz_widget *tw, char *opts[]);
void pdf_choice_widget_set_value(pdf_document *doc, fz_widget *tw, int n, char *opts[]);
+void pdf_set_doc_event_callback(pdf_document *doc, fz_doc_event_cb *event_cb, void *data);
+
+void pdf_event_issue_alert(pdf_document *doc, fz_alert_event *event);
/*
* Javascript handler
diff --git a/pdf/pdf_event.c b/pdf/pdf_event.c
new file mode 100644
index 00000000..37f88b20
--- /dev/null
+++ b/pdf/pdf_event.c
@@ -0,0 +1,34 @@
+#include "fitz.h"
+#include "mupdf-internal.h"
+
+typedef struct
+{
+ fz_doc_event base;
+ fz_alert_event alert;
+} fz_alert_event_internal;
+
+fz_alert_event *fz_access_alert_event(fz_doc_event *event)
+{
+ fz_alert_event *alert = NULL;
+
+ if (event->type == FZ_DOCUMENT_EVENT_ALERT)
+ alert = &((fz_alert_event_internal *)event)->alert;
+
+ return alert;
+}
+
+void pdf_event_issue_alert(pdf_document *doc, fz_alert_event *alert)
+{
+ fz_alert_event_internal ievent;
+ ievent.base.type = FZ_DOCUMENT_EVENT_ALERT;
+ ievent.alert = *alert;
+
+ if (doc->event_cb)
+ doc->event_cb((fz_doc_event *)&ievent, doc->event_cb_data);
+}
+
+void pdf_set_doc_event_callback(pdf_document *doc, fz_doc_event_cb *fn, void *data)
+{
+ doc->event_cb = fn;
+ doc->event_cb_data = data;
+}
diff --git a/pdf/pdf_js.c b/pdf/pdf_js.c
index fa33c44c..2a3c865c 100644
--- a/pdf/pdf_js.c
+++ b/pdf/pdf_js.c
@@ -13,6 +13,92 @@ struct pdf_js_s
pdf_jsimp_type *apptype;
};
+static pdf_jsimp_obj *app_alert(void *jsctx, void *obj, int argc, pdf_jsimp_obj *args[])
+{
+ pdf_js *js = (pdf_js *)jsctx;
+ fz_context *ctx = js->doc->ctx;
+ pdf_jsimp_obj *cMsg_obj = NULL;
+ pdf_jsimp_obj *nIcon_obj = NULL;
+ pdf_jsimp_obj *nType_obj = NULL;
+ pdf_jsimp_obj *cTitle_obj = NULL;
+ pdf_jsimp_obj *nButton_obj = NULL;
+ fz_alert_event event;
+ int arg_is_obj = 0;
+
+ if (argc < 1 || argc > 6)
+ return NULL;
+
+ event.message = "";
+ event.icon_type = FZ_ALERT_ICON_ERROR;
+ event.button_group_type = FZ_ALERT_BUTTON_GROUP_OK;
+ event.title = "MuPDF";
+ event.check_box_message = NULL;
+ event.button_pressed = 0;
+
+ fz_var(cMsg_obj);
+ fz_var(nIcon_obj);
+ fz_var(nType_obj);
+ fz_var(cTitle_obj);
+ fz_try(ctx)
+ {
+ arg_is_obj = (argc == 1 && pdf_jsimp_to_type(js->imp, args[0]) != JS_TYPE_STRING);
+ if (arg_is_obj)
+ {
+ cMsg_obj = pdf_jsimp_property(js->imp, args[0], "cMsg");
+ nIcon_obj = pdf_jsimp_property(js->imp, args[0], "nIcon");
+ nType_obj = pdf_jsimp_property(js->imp, args[0], "nType");
+ cTitle_obj = pdf_jsimp_property(js->imp, args[0], "cTitle");
+ }
+ else
+ {
+ switch (argc)
+ {
+ case 6:
+ case 5:
+ case 4:
+ cTitle_obj = args[3];
+ case 3:
+ nType_obj = args[2];
+ case 2:
+ nIcon_obj = args[1];
+ case 1:
+ cMsg_obj = args[0];
+ }
+ }
+
+ if (cMsg_obj)
+ event.message = pdf_jsimp_to_string(js->imp, cMsg_obj);
+
+ if (nIcon_obj)
+ event.icon_type = (int)pdf_jsimp_to_number(js->imp, nIcon_obj);
+
+ if (nType_obj)
+ event.button_group_type = (int)pdf_jsimp_to_number(js->imp, nType_obj);
+
+ if (cTitle_obj)
+ event.title = pdf_jsimp_to_string(js->imp, cTitle_obj);
+
+ pdf_event_issue_alert(js->doc, &event);
+ nButton_obj = pdf_jsimp_from_number(js->imp, (double)event.button_pressed);
+ }
+ fz_always(ctx)
+ {
+ if (arg_is_obj)
+ {
+ pdf_jsimp_drop_obj(js->imp, cMsg_obj);
+ pdf_jsimp_drop_obj(js->imp, nIcon_obj);
+ pdf_jsimp_drop_obj(js->imp, nType_obj);
+ pdf_jsimp_drop_obj(js->imp, cTitle_obj);
+ }
+ }
+ fz_catch(ctx)
+ {
+ fz_rethrow(ctx);
+ }
+
+ return nButton_obj;
+}
+
static pdf_obj *load_color(fz_context *ctx, pdf_jsimp *imp, pdf_jsimp_obj *val)
{
pdf_obj *col = NULL;
@@ -462,6 +548,7 @@ static void declare_dom(pdf_js *js)
/* Create the app type */
js->apptype = pdf_jsimp_new_type(imp, NULL);
+ pdf_jsimp_addmethod(imp, js->apptype, "alert", app_alert);
/* Create the document object and tell the engine to use */
pdf_jsimp_set_global_type(js->imp, js->doctype);