diff options
Diffstat (limited to 'support/hypertex/tanmoy/ghostview-1.5-hacked/callbacks.c')
-rw-r--r-- | support/hypertex/tanmoy/ghostview-1.5-hacked/callbacks.c | 749 |
1 files changed, 749 insertions, 0 deletions
diff --git a/support/hypertex/tanmoy/ghostview-1.5-hacked/callbacks.c b/support/hypertex/tanmoy/ghostview-1.5-hacked/callbacks.c new file mode 100644 index 0000000000..11b6fd4ca4 --- /dev/null +++ b/support/hypertex/tanmoy/ghostview-1.5-hacked/callbacks.c @@ -0,0 +1,749 @@ +/* + * callbacks.c -- X11 callbacks for ghostview. + * Copyright (C) 1992 Timothy O. Theisen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Tim Theisen Systems Programmer + * Internet: tim@cs.wisc.edu Department of Computer Sciences + * UUCP: uwvax!tim University of Wisconsin-Madison + * Phone: (608)262-0438 1210 West Dayton Street + * FAX: (608)262-9777 Madison, WI 53706 + */ + +/* This file is part of the hacked version of the ghostview package */ +/* which is distributed under the terms of the gnu license. The */ +/* modification referred to above is by Tanmoy Bhattacharya, */ +/* <tanmoy@qcd.lanl.gov> on Nov 17, 1994. Neither the modification, */ +/* nor the original program provides any warranty. */ + +#include <stdio.h> +#ifndef BUFSIZ +#define BUFSIZ 1024 +#endif + +#ifdef VMS +#define getenv _getenv +#endif + +extern char *getenv(); + +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#include <X11/Xaw/Cardinals.h> +#include <X11/Xaw/AsciiText.h> +#include <X11/Xaw/Scrollbar.h> +#include <X11/Xaw/Form.h> +#include <X11/Xaw/Command.h> + +#include "Ghostview.h" +#include "gv.h" +#include "ps.h" +#include "pdf.h" + +int pagehistory[1024], pageindex=0; + +/* Start application folding up by Destroying the top level widget. */ +/* The application exits when the last interpreter is killed during */ +/* a destroy callback from ghostview widgets. */ +void +quit_ghostview(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XtDestroyWidget(toplevel); +} + +/* Popup a window. */ +void +popup(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + positionpopup((Widget)client_data); + XtPopup((Widget)client_data, XtGrabNone); + XRaiseWindow(XtDisplay((Widget)client_data), XtWindow((Widget)client_data)); +} + +/* Popup a dialog box. */ +void +popup_dialog(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ +#ifdef SELFILE + Widget button; + String okay, cancel; + String name, init_path; + Arg args[1]; + FILE* fp; + struct stat sbuf; + extern FILE *XsraSelFile(); + + button = XtNameToWidget(dialog, "cancel"); + if (button) { + XtSetArg(args[0], XtNlabel, &cancel); + XtGetValues(button, args, ONE); + } + button = XtNameToWidget(dialog, "okay"); + if (button) { + XtSetArg(args[0], XtNlabel, &okay); + XtGetValues(button, args, ONE); + } +#endif + + mode = (int) client_data; + switch (mode) { + case PRINT_WHOLE: + case PRINT_MARKED: + SetDialogPrompt(dialog, app_res.print_prompt); + if (app_res.default_printer) + SetDialogResponse(dialog, app_res.default_printer); + else + ClearDialogResponse(dialog); + popup(w, (XtPointer)dialogpopup, call_data); + break; + case OPEN: +#ifdef SELFILE + if (filename && strcmp(filename, "-")) init_path = filename; + else init_path = NULL; + fp = XsraSelFile(toplevel, app_res.open_prompt, okay, cancel, + app_res.open_fail, init_path, "r", NULL, &name); + if (fp == NULL) break; + if (oldfilename) XtFree(oldfilename); + oldfilename = filename; + filename = name; + if (psfile) fclose(psfile); + psfile = fp; + stat(filename, &sbuf); + mtime = sbuf.st_mtime; + new_file(0); + show_page(0); +#else + SetDialogPrompt(dialog, app_res.open_prompt); + if (filename && strcmp(filename, "-")) + SetDialogResponse(dialog, filename); + else + ClearDialogResponse(dialog); + popup(w, dialogpopup, call_data); +#endif + break; + case SAVE: +#ifdef SELFILE + fp = XsraSelFile(toplevel, app_res.save_prompt, okay, cancel, + app_res.save_fail, "", "w", NULL, &name); + if (fp == NULL) break; + pscopydoc(fp); + fclose(fp); + XtFree(name); +#else + SetDialogPrompt(dialog, app_res.save_prompt); + ClearDialogResponse(dialog); + popup(w, dialogpopup, call_data); +#endif + break; + } +} + +/* Explicitly reopen the file. */ +void +reopen_file(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + extern int pagehistory[], pageindex; + struct stat sbuf; + int number = current_page; + + pdf_clear(); + fclose(psfile); + pageindex=0; + XtSetSensitive(backbutton, False); + psfile = fopen(filename, "r"); + mtime = sbuf.st_mtime; + if (oldfilename) XtFree(oldfilename); + oldfilename = XtNewString(filename); + new_file(number); + show_page(number); +} + +/* Get the selection, if no selection, get the insertion point. */ +/* If the new_page is different from the current page show it. */ +/* If not at the first page, show the previous page. */ +void +prev_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XawTextPosition pos, end; + int new_page; + + XawTextGetSelectionPos(toc, &pos, &end); + if (pos == end) { /* Nothing selected */ + pos = XawTextGetInsertionPoint(toc); + } + if ((new_page = pos/toc_entry_length) == current_page) { + new_page = current_page - 1; + } + if (new_page < 0) return; + show_page(new_page); +} + +void +back_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + extern int pagehistory[], pageindex; + if (pageindex>0) + show_page(pagehistory[--pageindex]); + else + prev_page(w, client_data, call_data); + + XtSetSensitive(backbutton, pageindex>0); + return; +} + +/* Get the selection, if no selection, get the insertion point. */ +/* Show this page. */ +void +this_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + if (toc_text) { + XawTextPosition pos, end; + int new_page; + + XawTextGetSelectionPos(toc, &pos, &end); + if (pos == end) { /* Nothing selected */ + pos = XawTextGetInsertionPoint(toc); + } + new_page = pos/toc_entry_length; + show_page(new_page); + } else { + GhostviewDisableInterpreter(page); + show_page(0); + } +} + +/* Get the selection, if no selection, get the insertion point. */ +/* If the new_page is different from the current page show it. */ +/* If not at the last page, show the next page. */ +void +next_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XawTextPosition pos, end; + int new_page = 0; + + if (toc_text) { + XawTextGetSelectionPos(toc, &pos, &end); + if (pos == end) { /* Nothing selected */ + pos = XawTextGetInsertionPoint(toc); + } + if ((new_page = pos/toc_entry_length) == current_page) { + new_page = current_page + 1; + } + if (new_page >= doc->numpages) return; + } + show_page(new_page); +} + +/* Center the viewport over the page */ +void +center_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + Arg args[2]; + Widget scroll; + float top, shown; + + scroll = XtNameToWidget(pageview, "vertical"); + if (scroll) { + XtSetArg(args[0], XtNshown, &shown); + XtSetArg(args[1], XtNtopOfThumb, &top); + XtGetValues(scroll, args, TWO); + + top = (1.0 - shown) / 2.0; + XtCallCallbacks(scroll, XtNjumpProc, &top); + } + + scroll = XtNameToWidget(pageview, "horizontal"); + if (scroll) { + XtSetArg(args[0], XtNshown, &shown); + XtSetArg(args[1], XtNtopOfThumb, &top); + XtGetValues(scroll, args, TWO); + + top = (1.0 - shown) / 2.0; + XtCallCallbacks(scroll, XtNjumpProc, &top); + } +} + +/* Get the selection, if no selection, get the insertion point. */ +/* Mark all pages in range, and cause toc to update. */ +void +mark_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XawTextPosition begin, end; + int i; + + XawTextGetSelectionPos(toc, &begin, &end); + if (begin == end) { /* Nothing selected */ + begin = end = XawTextGetInsertionPoint(toc); + } else { + end--; /* Sometimes end spills onto next line */ + } + for (i = begin/toc_entry_length; i <= end/toc_entry_length; i++) { + toc_text[i*toc_entry_length] = '*'; + XawTextInvalidate(toc, i*toc_entry_length, i*toc_entry_length+1); + } +} + +/* Get the selection, if no selection, get the insertion point. */ +/* Unmark all pages in range, and cause toc to update. */ +void +unmark_page(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XawTextPosition begin, end; + int i; + + XawTextGetSelectionPos(toc, &begin, &end); + if (begin == end) { /* Nothing selected */ + begin = end = XawTextGetInsertionPoint(toc); + } else { + end--; /* Sometimes end spills onto next line */ + } + for (i = begin/toc_entry_length; i <= end/toc_entry_length; i++) { + toc_text[i*toc_entry_length] = ' '; + XawTextInvalidate(toc, i*toc_entry_length, i*toc_entry_length+1); + } +} + +/* Set new magstep. Reshow the current page if magstep changed. */ +void +set_magstep(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + app_res.magstep = (int)client_data; + if (set_new_magstep()) { + layout_ghostview(); + show_page(current_page); + } +} + +/* Set new orientation. Reshow the current page if orientation changed. */ +void +set_orientation(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + app_res.force_orientation = force_setting; + app_res.orientation = (XtPageOrientation) client_data; + if (set_new_orientation(current_page)) { + layout_ghostview(); + show_page(current_page); + } +} + +/* Swap the landscape labels and change the flag. */ +void +swap_landscape(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + Arg args[1]; + String s1, s2; + + app_res.swap_landscape = !app_res.swap_landscape; + + XtSetArg(args[0], XtNlabel, &s1); + XtGetValues(landscapebutton, args, ONE); + s1 = XtNewString(s1); + XtSetArg(args[0], XtNlabel, &s2); + XtGetValues(seascapebutton, args, ONE); + s2 = XtNewString(s2); + XtSetArg(args[0], XtNlabel, s2); + XtSetValues(landscapebutton, args, ONE); + XtSetArg(args[0], XtNlabel, s1); + XtSetValues(seascapebutton, args, ONE); + XtFree(s1); + XtFree(s2); + + if (set_new_orientation(current_page)) { + layout_ghostview(); + show_page(current_page); + } +} + +/* Set new page media. If new page media is different, update app_resources */ +/* and redisplay page. */ +void +set_pagemedia(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + int new_pagemedia = (int) client_data; + if (new_pagemedia >= base_papersize) { + default_pagemedia = new_pagemedia; + app_res.force_pagemedia = force_setting; + } else { + document_media = new_pagemedia; + force_document_media = force_setting; + } + if (set_new_pagemedia(current_page)) { + layout_ghostview(); + show_page(current_page); + } +} + +/* track mouse pointer and popup zoom window */ +void +track_and_zoom(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + Arg args[20]; + Cardinal num_args; + Dimension width, height; + Widget zoom; + Widget zoomform; + Widget zoompage; + Widget zoomdismiss; + FILE *zoomfile; + struct stat sbuf; + GhostviewReturnStruct *p = (GhostviewReturnStruct *)call_data; + int llx; + int lly; + int urx; + int ury; + int bottom_margin; + int left_margin; + int right_margin; + int top_margin; + int i; + int gotopage; + + /* locator events have zero width and height */ + if ((p->width == 0) || (p->height == 0)) { + char buf[32]; + if (!app_res.show_locator) return; + sprintf(buf, "(%d, %d)", p->psx, p->psy); + XtSetArg(args[0], XtNlabel, buf); + XtSetValues(locator, args, ONE); + return; + } + + /* If no file, nothing to zoom. */ + if (!psfile) return; + + /* If in an anchor jump to instead */ + if ((gotopage=pdf_page(p->psx,p->psy))>=0) { + if(pageindex<sizeof(pagehistory)/sizeof(*pagehistory)-1) + pagehistory[pageindex++] = current_page; + XtSetSensitive(backbutton, True); + show_page(gotopage); return; + } + + /* If the file changed, cannot zoom */ + stat(filename, &sbuf); + if (mtime != sbuf.st_mtime) return; + zoom = XtCreatePopupShell("zoom", topLevelShellWidgetClass, + toplevel, NULL, ZERO); + + zoomform = XtCreateManagedWidget("form", formWidgetClass, + zoom, NULL, ZERO); + + llx = p->psx - p->width/2; + lly = p->psy - p->height/2; + urx = p->psx + p->width/2; + ury = p->psy + p->height/2; + + /* Make sure zoom window doesn't go off the edge of the page */ + if (llx < current_llx) { + llx = current_llx; + urx = llx + p->width; + } + if (lly < current_lly) { + lly = current_lly; + ury = lly + p->height; + } + if (urx > current_urx) { + urx = current_urx; + llx = urx - p->width; + } + if (ury > current_ury) { + ury = current_ury; + lly = ury - p->height; + } + if (llx < current_llx) { + llx = current_llx; + } + if (lly < current_lly) { + lly = current_lly; + } + bottom_margin = lly - current_lly; + left_margin = llx - current_llx; + right_margin = current_urx - urx; + top_margin = current_ury - ury; + + num_args = 0; + XtSetArg(args[num_args], XtNtop, XtChainTop); num_args++; + XtSetArg(args[num_args], XtNbottom, XtChainBottom); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainRight); num_args++; + XtSetArg(args[num_args], XtNorientation, current_orientation); + num_args++; + XtSetArg(args[num_args], XtNllx, llx); num_args++; + XtSetArg(args[num_args], XtNlly, lly); num_args++; + XtSetArg(args[num_args], XtNurx, urx); num_args++; + XtSetArg(args[num_args], XtNury, ury); num_args++; + XtSetArg(args[num_args], XtNbottomMargin, bottom_margin); + num_args++; + XtSetArg(args[num_args], XtNleftMargin, left_margin); + num_args++; + XtSetArg(args[num_args], XtNrightMargin, right_margin); + num_args++; + XtSetArg(args[num_args], XtNtopMargin, top_margin); num_args++; + XtSetArg(args[num_args], XtNbottomMargin, bottom_margin); + num_args++; + XtSetFloatArg(args[num_args], XtNxdpi, p->xdpi); num_args++; + XtSetFloatArg(args[num_args], XtNydpi, p->ydpi); num_args++; + if (!toc_text) { + XtSetArg(args[num_args], XtNfilename, filename); num_args++; + } + zoompage = XtCreateManagedWidget("page", ghostviewWidgetClass, + zoomform, args, num_args); + num_ghosts++; + XtAddCallback(zoompage, XtNcallback, track_and_zoom, (XtPointer)0); + XtAddCallback(zoompage, XtNmessageCallback, message, (XtPointer)zoompage); + XtAddCallback(zoompage, XtNdestroyCallback, destroy_ghost, + (XtPointer)zoompage); + + num_args = 0; + XtSetArg(args[num_args], XtNfromVert, zoompage); num_args++; + XtSetArg(args[num_args], XtNtop, XtChainBottom); num_args++; + XtSetArg(args[num_args], XtNbottom, XtChainBottom); num_args++; + XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++; + XtSetArg(args[num_args], XtNright, XtChainRight); num_args++; + zoomdismiss = XtCreateManagedWidget("dismiss", commandWidgetClass, + zoomform, args, num_args); + XtAddCallback(zoomdismiss, XtNcallback, destroy, (XtPointer)zoom); + + XtSetArg(args[0], XtNwidth, &width); + XtGetValues(zoompage, args, ONE); + XtSetArg(args[0], XtNwidth, width); + XtSetValues(zoomdismiss, args, ONE); + + XtRealizeWidget(zoom); + positionpopup(zoom); + + num_args = 0; + XtSetArg(args[num_args], XtNwidth, &width); num_args++; + XtSetArg(args[num_args], XtNheight, &height); num_args++; + XtGetValues(zoom, args, num_args); + + num_args = 0; + XtSetArg(args[num_args], XtNminWidth, width); num_args++; + XtSetArg(args[num_args], XtNminHeight, height); num_args++; + XtSetArg(args[num_args], XtNmaxWidth, width); num_args++; + XtSetArg(args[num_args], XtNmaxHeight, height); num_args++; + XtSetValues(zoom, args, num_args); + XSetWMProtocols(XtDisplay(zoom), XtWindow(zoom), &wm_delete_window, 1); + XtPopup(zoom, XtGrabNone); + + if (toc_text) { + zoomfile = fopen(filename, "r"); + if (zoomfile == NULL) return; + GhostviewSendPS(zoompage, zoomfile, doc->beginprolog, + doc->lenprolog, False); + GhostviewSendPS(zoompage, zoomfile, doc->beginsetup, + doc->lensetup, False); + if (doc->pageorder == DESCEND) + i = (doc->numpages - 1) - current_page; + else + i = current_page; + GhostviewSendPS(zoompage, zoomfile, doc->pages[i].begin, + doc->pages[i].len, True); + } +} + +/* Process messages from ghostscript */ +/* Refresh occurs when window was resized unexpectedly */ +void +message(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + int i; + char *error; + + if (!strcmp((char *) call_data, "Failed")) { + if ((Widget)client_data == page) { + error = "Error: PostScript interpreter failed in main window.\n\n"; + } else { + error = "Error: PostScript interpreter failed in zoom window.\n\n"; + } + output(w, NULL, error); + } else if (!strcmp((char *) call_data, "BadAlloc")) { + if ((Widget)client_data == page) { + error = + "Warning: Could not allocate backing pixmap in main window.\n\n"; + } else { + error = + "Warning: Could not allocate backing pixmap in zoom window.\n\n"; + } + output(w, NULL, error); + } else if (!strcmp((char *) call_data, "Refresh")) { + if (toc_text) { + GhostviewSendPS(w, psfile, doc->beginprolog, + doc->lenprolog, False); + GhostviewSendPS(w, psfile, doc->beginsetup, + doc->lensetup, False); + if (doc->pageorder == DESCEND) + i = (doc->numpages - 1) - current_page; + else + i = current_page; + GhostviewSendPS(w, psfile, doc->pages[i].begin, + doc->pages[i].len, False); + } + } +} + +/* Take output from ghostscript and display it in the infotext popup window */ +void +output(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + Arg args[2]; + XawTextBlock message_block; + + message_block.firstPos = 0; + message_block.length = strlen(call_data); + message_block.ptr = call_data; + message_block.format = FMT8BIT; + + XawTextDisableRedisplay(infotext); + + XtSetArg(args[0], XtNeditType, XawtextAppend); + XtSetValues(infotext, args, ONE); + XawTextReplace(infotext, info_length, info_length, &message_block); + info_length = info_length + message_block.length; + + XtSetArg(args[0], XtNeditType, XawtextRead); + XtSetArg(args[1], XtNinsertPosition, info_length); + XtSetValues(infotext, args, TWO); + XawTextEnableRedisplay(infotext); + if (!info_up) XtPopup(infopopup, XtGrabNone); + info_up = True; +} + +/* Dismiss popup dialog */ +void +okay(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + String name, error; + Widget dialog; + + dialog = (Widget)client_data; + name = GetDialogResponse(dialog); + switch (mode) { + case PRINT_WHOLE: + case PRINT_MARKED: + if (error = print_file(name, (mode == PRINT_WHOLE))) { + char *buf = XtMalloc(strlen(error) + + strlen(app_res.print_prompt) + 2); + sprintf(buf, "%s\n%s", error, app_res.print_prompt); + SetDialogPrompt(dialog, buf); + XtFree(error); + XtFree(buf); + } else { + XtPopdown(XtParent(dialog)); + } + break; + case OPEN: + if (error = open_file(name)) { + char *buf = XtMalloc(strlen(error) + + strlen(app_res.open_prompt) + 2); + sprintf(buf, "%s\n%s", error, app_res.open_prompt); + SetDialogPrompt(dialog, buf); + XtFree(error); + XtFree(buf); + } else { + XtPopdown(XtParent(dialog)); + } + break; + case SAVE: + if (error = save_file(name)) { + char *buf = XtMalloc(strlen(error) + + strlen(app_res.save_prompt) + 2); + sprintf(buf, "%s\n%s", error, app_res.save_prompt); + SetDialogPrompt(dialog, buf); + XtFree(error); + XtFree(buf); + } else { + XtPopdown(XtParent(dialog)); + } + break; + } + XtFree(name); +} + +/* Dismiss popup window */ +void +dismiss(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XtPopdown((Widget)client_data); + if ((Widget)client_data == infopopup) info_up = False; +} + +/* Destroy popup window */ +void +destroy(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + XtDestroyWidget((Widget)client_data); +} + +/* destroy callback for Ghostview widgets. */ +/* The disable interpreter call ensures that ghostscript is killed. */ +/* One the count goes to 0, we are sure that all forked processes have */ +/* been killed and that we can safely exit. */ +void +destroy_ghost(w, client_data, call_data) + Widget w; + XtPointer client_data, call_data; +{ + GhostviewDisableInterpreter((Widget) client_data); + num_ghosts--; + if (num_ghosts) return; + if (dying) old_Xerror(XtDisplay(w), &bomb); + XtDestroyApplicationContext(app_con); + exit(0); +} |