diff options
-rw-r--r-- | android/jni/Core.mk | 1 | ||||
-rw-r--r-- | apps/jstest_main.c | 16 | ||||
-rw-r--r-- | apps/pdfapp.c | 22 | ||||
-rw-r--r-- | apps/pdfapp.h | 1 | ||||
-rw-r--r-- | apps/win_main.c | 56 | ||||
-rw-r--r-- | apps/x11_main.c | 16 | ||||
-rw-r--r-- | fitz/doc_interactive.c | 5 | ||||
-rw-r--r-- | fitz/fitz.h | 3 | ||||
-rw-r--r-- | pdf/mupdf-internal.h | 6 | ||||
-rw-r--r-- | pdf/pdf_event.c | 34 | ||||
-rw-r--r-- | pdf/pdf_js.c | 87 | ||||
-rw-r--r-- | win32/libmupdf-v8.vcproj | 4 | ||||
-rw-r--r-- | win32/libmupdf.vcproj | 4 |
13 files changed, 254 insertions, 1 deletions
diff --git a/android/jni/Core.mk b/android/jni/Core.mk index a156fbf8..fcfc3412 100644 --- a/android/jni/Core.mk +++ b/android/jni/Core.mk @@ -86,6 +86,7 @@ LOCAL_SRC_FILES := \ $(MY_ROOT)/pdf/pdf_colorspace.c \ $(MY_ROOT)/pdf/pdf_crypt.c \ $(MY_ROOT)/pdf/pdf_encoding.c \ + $(MY_ROOT)/pdf/pdf_event.c \ $(MY_ROOT)/pdf/pdf_font.c \ $(MY_ROOT)/pdf/pdf_fontfile.c \ $(MY_ROOT)/pdf/pdf_form.c \ diff --git a/apps/jstest_main.c b/apps/jstest_main.c index bb2f4afd..a6ff06d1 100644 --- a/apps/jstest_main.c +++ b/apps/jstest_main.c @@ -37,6 +37,22 @@ void winerror(pdfapp_t *app, char *msg) exit(1); } +void winalert(pdfapp_t *app, fz_alert_event *alert) +{ + fprintf(stderr, "Alert %s: %s", alert->title, alert->message); + switch (alert->button_group_type) + { + case FZ_ALERT_BUTTON_GROUP_OK: + case FZ_ALERT_BUTTON_GROUP_OK_CANCEL: + alert->button_pressed = FZ_ALERT_BUTTON_OK; + break; + case FZ_ALERT_BUTTON_GROUP_YES_NO: + case FZ_ALERT_BUTTON_GROUP_YES_NO_CANCEL: + alert->button_pressed = FZ_ALERT_BUTTON_YES; + break; + } +} + static char pd_password[256] = ""; static char td_textinput[LONGLINE] = ""; diff --git a/apps/pdfapp.c b/apps/pdfapp.c index 3468e07d..0a87565a 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -101,6 +101,21 @@ void pdfapp_invert(pdfapp_t *app, fz_bbox rect) fz_invert_pixmap_rect(app->image, rect); } +static void event_cb(fz_doc_event *event, void *data) +{ + pdfapp_t *app = (pdfapp_t *)data; + + switch (event->type) + { + case FZ_DOCUMENT_EVENT_ALERT: + { + fz_alert_event *alert = fz_access_alert_event(event); + winalert(app, alert); + } + break; + } +} + void pdfapp_open(pdfapp_t *app, char *filename, int reload) { fz_context *ctx = app->ctx; @@ -108,8 +123,15 @@ void pdfapp_open(pdfapp_t *app, char *filename, int reload) fz_try(ctx) { + fz_interactive *idoc; + app->doc = fz_open_document(ctx, filename); + idoc = fz_interact(app->doc); + + if (idoc) + fz_set_doc_event_callback(idoc, event_cb, app); + if (fz_needs_password(app->doc)) { int okay = fz_authenticate_password(app->doc, password); diff --git a/apps/pdfapp.h b/apps/pdfapp.h index 43bc7b3b..46dcf291 100644 --- a/apps/pdfapp.h +++ b/apps/pdfapp.h @@ -37,6 +37,7 @@ extern void winhelp(pdfapp_t*); extern void winfullscreen(pdfapp_t*, int state); extern int winsavequery(pdfapp_t*); extern int wingetsavepath(pdfapp_t*, char *buf, int len); +extern void winalert(pdfapp_t *, fz_alert_event *alert); struct pdfapp_s { diff --git a/apps/win_main.c b/apps/win_main.c index 025e38db..97f927f2 100644 --- a/apps/win_main.c +++ b/apps/win_main.c @@ -99,6 +99,62 @@ void winerror(pdfapp_t *app, char *msg) exit(1); } +void winalert(pdfapp_t *app, fz_alert_event *alert) +{ + int buttons = MB_OK; + int icon = MB_ICONWARNING; + int pressed = FZ_ALERT_BUTTON_NONE; + + switch (alert->icon_type) + { + case FZ_ALERT_ICON_ERROR: + icon = MB_ICONERROR; + break; + case FZ_ALERT_ICON_WARNING: + icon = MB_ICONWARNING; + break; + case FZ_ALERT_ICON_QUESTION: + icon = MB_ICONQUESTION; + break; + case FZ_ALERT_ICON_STATUS: + icon = MB_ICONINFORMATION; + break; + } + + switch (alert->button_group_type) + { + case FZ_ALERT_BUTTON_GROUP_OK: + buttons = MB_OK; + break; + case FZ_ALERT_BUTTON_GROUP_OK_CANCEL: + buttons = MB_OKCANCEL; + break; + case FZ_ALERT_BUTTON_GROUP_YES_NO: + buttons = MB_YESNO; + break; + case FZ_ALERT_BUTTON_GROUP_YES_NO_CANCEL: + buttons = MB_YESNOCANCEL; + break; + } + + pressed = MessageBoxA(hwndframe, alert->message, alert->title, icon|buttons); + + switch (pressed) + { + case IDOK: + alert->button_pressed = FZ_ALERT_BUTTON_OK; + break; + case IDCANCEL: + alert->button_pressed = FZ_ALERT_BUTTON_CANCEL; + break; + case IDNO: + alert->button_pressed = FZ_ALERT_BUTTON_NO; + break; + case IDYES: + alert->button_pressed = FZ_ALERT_BUTTON_YES; + } +} + int winsavequery(pdfapp_t *app) { switch(MessageBoxA(hwndframe, "File has unsaved changes. Do you want to save", "MuPDF", MB_YESNOCANCEL)) diff --git a/apps/x11_main.c b/apps/x11_main.c index 623187fa..182aadb4 100644 --- a/apps/x11_main.c +++ b/apps/x11_main.c @@ -110,6 +110,22 @@ void winwarn(pdfapp_t *app, char *msg) fprintf(stderr, "mupdf: warning: %s\n", msg); } +void winalert(pdfapp_t *app, fz_alert_event *alert) +{ + fprintf(stderr, "Alert %s: %s", alert->title, alert->message); + switch (alert->button_group_type) + { + case FZ_ALERT_BUTTON_GROUP_OK: + case FZ_ALERT_BUTTON_GROUP_OK_CANCEL: + alert->button_pressed = FZ_ALERT_BUTTON_OK; + break; + case FZ_ALERT_BUTTON_GROUP_YES_NO: + case FZ_ALERT_BUTTON_GROUP_YES_NO_CANCEL: + alert->button_pressed = FZ_ALERT_BUTTON_YES; + break; + } +} + char *winpassword(pdfapp_t *app, char *filename) { char *r = password; diff --git a/fitz/doc_interactive.c b/fitz/doc_interactive.c index b5d54549..f0a4f2ba 100644 --- a/fitz/doc_interactive.c +++ b/fitz/doc_interactive.c @@ -75,3 +75,8 @@ void fz_choice_widget_set_value(fz_interactive *idoc, fz_widget *tw, int n, char { pdf_choice_widget_set_value((pdf_document *)idoc, tw, n, opts); } + +void fz_set_doc_event_callback(fz_interactive *idoc, fz_doc_event_cb *event_cb, void *data) +{ + pdf_set_doc_event_callback((pdf_document *)idoc, event_cb, data); +} diff --git a/fitz/fitz.h b/fitz/fitz.h index cfd2db9f..4e5607f3 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -2602,6 +2602,7 @@ void fz_set_doc_event_callback(fz_interactive *idoc, fz_doc_event_cb *fn, void * */ typedef struct { + char *message; int icon_type; int button_group_type; char *title; @@ -2645,7 +2646,7 @@ enum structire are owned by mupdf and need not be freed by the caller. */ -fz_alert_event *fz_access_alert_event(fz_interactive *idoc); +fz_alert_event *fz_access_alert_event(fz_doc_event *event); /* fz_submit_event: details of a submit event. The app should submit 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); diff --git a/win32/libmupdf-v8.vcproj b/win32/libmupdf-v8.vcproj index e1a5a97f..45f7f7b9 100644 --- a/win32/libmupdf-v8.vcproj +++ b/win32/libmupdf-v8.vcproj @@ -259,6 +259,10 @@ > </File> <File + RelativePath="..\pdf\pdf_event.c" + > + </File> + <File RelativePath="..\pdf\pdf_font.c" > </File> diff --git a/win32/libmupdf.vcproj b/win32/libmupdf.vcproj index 2715588d..f8f14908 100644 --- a/win32/libmupdf.vcproj +++ b/win32/libmupdf.vcproj @@ -258,6 +258,10 @@ > </File> <File + RelativePath="..\pdf\pdf_event.c" + > + </File> + <File RelativePath="..\pdf\pdf_font.c" > </File> |