diff options
-rw-r--r-- | ScrollByL.c | 33 | ||||
-rw-r--r-- | ScrollByL.h | 4 | ||||
-rw-r--r-- | ScrollByLP.h | 4 | ||||
-rw-r--r-- | Xman-noxprint.ad | 195 | ||||
-rw-r--r-- | Xman-xprint.ad | 292 | ||||
-rw-r--r-- | buttons.c | 33 | ||||
-rw-r--r-- | defs.h | 7 | ||||
-rw-r--r-- | handler.c | 123 | ||||
-rw-r--r-- | main.c | 11 | ||||
-rw-r--r-- | man.c | 27 | ||||
-rw-r--r-- | man.h | 45 | ||||
-rw-r--r-- | misc.c | 222 | ||||
-rw-r--r-- | print.c | 377 | ||||
-rw-r--r-- | print.h | 47 | ||||
-rw-r--r-- | search.c | 2 | ||||
-rw-r--r-- | vendor.h | 13 | ||||
-rw-r--r-- | version.h | 2 |
17 files changed, 1328 insertions, 109 deletions
diff --git a/ScrollByL.c b/ScrollByL.c index 9f8c359..c679145 100644 --- a/ScrollByL.c +++ b/ScrollByL.c @@ -93,6 +93,10 @@ static XtResource resources[] = { Offset(symbol_font), XtRString, MANPAGE_SYMBOL}, {XtNfile, XtCFile, XtRFile, sizeof(FILE *), Offset(file), XtRImmediate, (caddr_t) NULL}, + {XtNNumTotalLines, XtCNumTotalLines, XtRInt, sizeof(int), + Offset(lines), XtRImmediate, (caddr_t) 0}, + {XtNNumVisibleLines, XtCNumVisibleLines, XtRInt, sizeof(int), + Offset(num_visible_lines), XtRImmediate, (caddr_t) 0}, }; #undef Offset @@ -104,6 +108,7 @@ static XtResource resources[] = { * ****************************************************************/ +static void CreateScrollbar(Widget w); static Boolean ScrollVerticalText(Widget w, int new_line, Boolean force_redisp); static void Layout(Widget w); static void LoadFile(Widget w); @@ -197,6 +202,8 @@ Layout(Widget w) Widget bar; Position bar_bw; + CreateScrollbar(w); + /* * For now always show the bar. */ @@ -222,6 +229,8 @@ Layout(Widget w) XtResizeWidget(bar, bar->core.width, height, bar->core.border_width); SetThumbHeight(w); + + sblw->scroll.num_visible_lines = height / sblw->scroll.font_height + 1; } /* ARGSUSED */ @@ -277,22 +286,20 @@ static void PaintText(Widget w, int y_loc, int height) { ScrollByLineWidget sblw = (ScrollByLineWidget) w; - int start_line, num_lines, location; + int start_line, location; start_line = y_loc / sblw->scroll.font_height + sblw->scroll.line_pointer; if (start_line >= sblw->scroll.lines) return; - num_lines = height / sblw->scroll.font_height + 1; - /* * Only integer arithmetic makes this possible. */ location = y_loc / sblw->scroll.font_height * sblw->scroll.font_height; - PrintText(w, start_line, num_lines, location); + PrintText(w, start_line, sblw->scroll.num_visible_lines, location); } /* Function Name: Page @@ -384,7 +391,7 @@ int new_line, Boolean force_redisp) { ScrollByLineWidget sblw = (ScrollByLineWidget) w; - int num_lines = (int)w->core.height / sblw->scroll.font_height + 1; + int num_lines = sblw->scroll.num_visible_lines; int max_lines, old_line; Boolean move_thumb = FALSE; @@ -598,8 +605,6 @@ VerticalScroll(Widget w, XtPointer client_data, XtPointer call_data) SetThumb( (Widget) sblw); } -int h_width; /* main font width */ - /* ARGSUSED */ static void Initialize(Widget req, Widget new, ArgList args, Cardinal *num_args) @@ -619,12 +624,9 @@ Initialize(Widget req, Widget new, ArgList args, Cardinal *num_args) atomNum = XInternAtom(XtDisplay(req), "FIGURE_WIDTH", False); if (XGetFontProperty(sblw->scroll.normal_font, atomNum, &figWidth)) - h_width = figWidth; + sblw->scroll.h_width = figWidth; else - h_width = XTextWidth(sblw->scroll.normal_font, "$", 1); - - - + sblw->scroll.h_width = XTextWidth(sblw->scroll.normal_font, "$", 1); } /* Initialize. */ /* Function Name: CreateGCs @@ -721,7 +723,7 @@ static Boolean SetValuesHook(Widget w, ArgList args, Cardinal *num_args) { Boolean ret = TRUE; - int i; + Cardinal i; for (i = 0; i < *num_args; i++) { if (strcmp(XtNfile, args[i].name) == 0) { @@ -819,6 +821,7 @@ LoadFile(Widget w) * Copy the file into memory. */ + fseek(file, 0L, SEEK_SET); if (fread(page, sizeof(char), fileinfo.st_size, file) == 0) XtAppError(XtWidgetToApplicationContext(w), "SBLW LoadFile: Failure in fread."); @@ -1021,7 +1024,7 @@ PrintText(Widget w, int start_line, int num_lines, int location) italicflag = FALSE; x_loc = sblw->scroll.offset + sblw->scroll.indent; h_col = h_col + 8 - (h_col%8); - x_loc += h_width * h_col; + x_loc += sblw->scroll.h_width * h_col; break; case ' ': @@ -1042,7 +1045,7 @@ PrintText(Widget w, int start_line, int num_lines, int location) x_loc = sblw->scroll.offset + sblw->scroll.indent; h_col += (h_c - c); - x_loc += h_width * h_col; + x_loc += sblw->scroll.h_width * h_col; c = h_c - 1; break; diff --git a/ScrollByL.h b/ScrollByL.h index cdf8e2e..0283893 100644 --- a/ScrollByL.h +++ b/ScrollByL.h @@ -60,8 +60,12 @@ from the X Consortium. #define XtNmanualFontBold "manualFontBold" #define XtNmanualFontItalic "manualFontItalic" #define XtNmanualFontSymbol "manualFontSymbol" +#define XtNNumTotalLines "numTotalLines" +#define XtNNumVisibleLines "numVisibleLines" #define XtCIndent "Indent" +#define XtCNumTotalLines "NumTotalLines" +#define XtCNumVisibleLines "NumVisibleLines" /* Class record constants */ diff --git a/ScrollByLP.h b/ScrollByLP.h index 0947707..25402d7 100644 --- a/ScrollByLP.h +++ b/ScrollByLP.h @@ -68,6 +68,7 @@ typedef struct _ScrollByLinePart { * normal_font, * italic_font, * symbol_font; + int h_width; /* Main font width */ /* variables not in resource list. */ @@ -80,7 +81,8 @@ typedef struct _ScrollByLinePart { GC bold_gc, normal_gc, italic_gc, symbol_gc; /* gc for drawing. */ char ** top_line; /* The top line of the file. */ - int lines; /* number of line in the file. */ + int lines; /* Total number of line in the file. */ + int num_visible_lines; /* Number of lines visible */ } ScrollByLinePart; /**************************************************************** diff --git a/Xman-noxprint.ad b/Xman-noxprint.ad new file mode 100644 index 0000000..3f08b02 --- /dev/null +++ b/Xman-noxprint.ad @@ -0,0 +1,195 @@ +*input: True + +*topBox: True +*topBox.Title: Xman +*topBox.IconName: Xman + +*manualBrowser.Title: Manual Page +*manualBrowser.IconName: Manual Page +*manualBrowser.geometry: 600x600 + +*manualFontBold: -*-courier-bold-r-*-*-*-120-*-*-*-*-*-* +*manualFontItalic: -*-courier-medium-o-*-*-*-120-*-*-*-*-*-* +*manualFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*manualFontSymbol: -*-symbol-*-*-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*directoryFontNormal: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-lucida-bold-r-*-*-*-120-*-*-*-*-*-* + +!*SimpleMenu.BackingStore: Always +!*SimpleMenu.SaveUnder: Off + +*horizPane.orientation: horizontal +*horizPane*showGrip: False +*horizPane.min: 22 +*horizPane.max: 22 +*topLabel.BorderWidth: 0 +*search*label.BorderWidth: 0 + +*search*dialog*value: Xman + +!*optionMenu.Label: Options +!*sectionMenu.Label: Sections + +*horizPane*options.Label: Options +*horizPane*sections.Label: Sections + +*helpButton.Label: Help +*helpButton.Tip: Open help browser + +*quitButton.Label: Quit +*quitButton.Tip: Quit Xman + +*manpageButton.Label: Manual Page +*manpageButton.Tip: Open new manpage browser + +*topLabel.Label: Manual Browser + +!*SimpleMenu*menuLabel*vertSpace: 100 +!*SimpleMenu*menuLabel*leftMargin: 20 + +*displayDirectory.Label: Display Directory +*displayManualPage.Label: Display Manual Page +*help.Label: Help +*help.geometry: 600x600 +*search.Label: Search +*removeThisManpage.Label: Remove This Manpage +*help*removeThisManpage.Label: Remove Help +*openNewManpage.Label: Open New Manpage +*showVersion.Label: Show Version +*quit.Label: Quit + +*pleaseStandBy*Label: Formatting Manual Page, Please Stand By... + +*search*dialog.Label: Type string to search for: +*search*apropos.Label: Apropos +*search*manualPage.Label: Manual Page +*search*cancel.Label: Cancel + +*likeToSave*dialog.Label: Would you like to save this formatted Manual Page? +*likeToSave*yes.Label: Yes +*likeToSave*no.Label: No + +*translations: #override \ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>s: PopupSearch() + +*help*Paned.manualPage.translations:#override \ + Ctrl<Btn1Down>: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>r: RemoveThisManpage() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>d: GotoPage(Directory) \n\ + Ctrl<Key>m: GotoPage(ManualPage) \n\ + Ctrl<Key>v: ShowVersion() \n\ + <Key>Prior: Page(Back) \n\ + <Key>Next : Page(Forward) \n\ + Shift<Btn4Down>,<Btn4Up>: Page(Line,-1) \n\ + Shift<Btn5Down>,<Btn5Up>: Page(Line,1) \n\ + Ctrl<Btn4Down>,<Btn4Up>: Page(Back) \n\ + Ctrl<Btn5Down>,<Btn5Up>: Page(Forward) \n\ + None<Btn4Down>,<Btn4Up>: Page(Line,-5) \n\ + None<Btn5Down>,<Btn5Up>: Page(Line,5) + +*manualBrowser*manualPage.translations: #override \ + Ctrl<Btn1Down>: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl<Btn2Down>: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift<Btn2Down>,<Btn2Up>:GotoPage(Directory)\n\ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>r: RemoveThisManpage() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>d: GotoPage(Directory) \n\ + Ctrl<Key>m: GotoPage(ManualPage) \n\ + Ctrl<Key>v: ShowVersion() \n\ + <Key>Prior: Page(Back) \n\ + <Key>Next : Page(Forward) \n\ + Shift<Btn4Down>,<Btn4Up>: Page(Line,-1) \n\ + Shift<Btn5Down>,<Btn5Up>: Page(Line,1) \n\ + Ctrl<Btn4Down>,<Btn4Up>: Page(Back) \n\ + Ctrl<Btn5Down>,<Btn5Up>: Page(Forward) \n\ + None<Btn4Down>,<Btn4Up>: Page(Line,-5) \n\ + None<Btn5Down>,<Btn5Up>: Page(Line,5) \n\ + Ctrl<Key>s: PopupSearch() + +!*manualBrowser*directory.background: Grey80 +*manualBrowser*directory.translations: #override \ + Ctrl<Btn1Down>: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl<Btn2Down>: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift<Btn2Down>,<Btn2Up>: GotoPage(Manpage) \n\ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>r: RemoveThisManpage() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>d: GotoPage(Directory) \n\ + Ctrl<Key>m: GotoPage(ManualPage) \n\ + Ctrl<Key>v: ShowVersion() \n\ + Ctrl<Key>s: PopupSearch() + +*manualBrowser*search*manualPage.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Manpage) reset() + +*manualBrowser*search*apropos.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Apropos) reset() + +*manualBrowser*search*cancel*translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Cancel) reset() + +*manualBrowser*search*value*translations: #override \ + <Key>Return: Search(Manpage) \n\ + Ctrl<Key>m: Search(Manpage) + +*topBox*search*manualPage.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Manpage, Open) reset() + +*topBox*search*apropos.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Apropos, Open) reset() + +*topBox*search*cancel*translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Cancel, Open) reset() + +*topBox*search*value*translations: #override \ + <Key>Return: Search(Manpage, Open) \n\ + Ctrl<Key>m: Search(Manpage, Open) + +*manualBrowser*likeToSave*yes.translations: #override \ + <Btn1Down>,<Btn1Up>: SaveFormattedPage(Save) reset() \n\ + <Key>y: SaveFormattedPage(Save) \n\ + <Key>n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*no.translations: #override \ + <Btn1Down>,<Btn1Up>: SaveFormattedPage(Cancel) reset() \n\ + <Key>y: SaveFormattedPage(Save) \n\ + <Key>n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*translations: #override \ + <Key>y: SaveFormattedPage(Save) \n\ + <Key>n: SaveFormattedPage(Cancel) + +*helpButton.translations: #augment \ + <Btn1Down>,<Btn1Up>: PopupHelp() reset() + +*quitButton.translations: #augment \ + <Btn1Down>,<Btn1Up>: Quit() reset() + +*manpageButton.translations: #augment \ + <Btn1Down>,<Btn1Up>: CreateNewManpage() reset() + +! EOF. diff --git a/Xman-xprint.ad b/Xman-xprint.ad new file mode 100644 index 0000000..8b342a2 --- /dev/null +++ b/Xman-xprint.ad @@ -0,0 +1,292 @@ +*input: True + +*topBox: True +*topBox.Title: Xman +*topBox.IconName: Xman + +*manualBrowser.Title: Manual Page +*manualBrowser.IconName: Manual Page +*manualBrowser.geometry: 600x600 + +*manualFontBold: -*-courier-bold-r-*-*-*-120-*-*-*-*-*-* +*manualFontItalic: -*-courier-medium-o-*-*-*-120-*-*-*-*-*-* +*manualFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*manualFontSymbol: -*-symbol-*-*-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-courier-medium-r-*-*-*-120-*-*-*-*-*-* +*directoryFontNormal: -*-helvetica-medium-r-*-*-*-120-*-*-*-*-*-* +!*directoryFontNormal: -*-lucida-bold-r-*-*-*-120-*-*-*-*-*-* + +!*SimpleMenu.BackingStore: Always +!*SimpleMenu.SaveUnder: Off + +*horizPane.orientation: horizontal +*horizPane*showGrip: False +*horizPane.min: 22 +*horizPane.max: 22 +*topLabel.BorderWidth: 0 +*search*label.BorderWidth: 0 + +*search*dialog*value: Xman + +!*optionMenu.Label: Options +!*sectionMenu.Label: Sections + +*horizPane*options.Label: Options +*horizPane*sections.Label: Sections + +*helpButton.Label: Help +*helpButton.Tip: Open help browser + +*quitButton.Label: Quit +*quitButton.Tip: Quit Xman + +*manpageButton.Label: Manual Page +*manpageButton.Tip: Open new manpage browser + +*topLabel.Label: Manual Browser + +!*SimpleMenu*menuLabel*vertSpace: 100 +!*SimpleMenu*menuLabel*leftMargin: 20 + +*displayDirectory.Label: Display Directory +*displayManualPage.Label: Display Manual Page +*help.Label: Help +*help.geometry: 600x600 +*search.Label: Search +*removeThisManpage.Label: Remove This Manpage +*help*removeThisManpage.Label: Remove Help +*openNewManpage.Label: Open New Manpage +*printManualPage.Label: Print This Manpage +*showVersion.Label: Show Version +*quit.Label: Quit + +*pleaseStandBy*Label: Formatting Manual Page, Please Stand By... + +*search*dialog.Label: Type string to search for: +*search*apropos.Label: Apropos +*search*manualPage.Label: Manual Page +*search*cancel.Label: Cancel + +*likeToSave*dialog.Label: Would you like to save this formatted Manual Page? +*likeToSave*yes.Label: Yes +*likeToSave*no.Label: No + +*translations: #override \ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>s: PopupSearch() + +*help*Paned.manualPage.translations:#override \ + Ctrl<Btn1Down>: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>r: RemoveThisManpage() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>d: GotoPage(Directory) \n\ + Ctrl<Key>m: GotoPage(ManualPage) \n\ + Ctrl<Key>p: PrintThisManpage() \n\ + Ctrl<Key>v: ShowVersion() \n\ + <Key>Prior: Page(Back) \n\ + <Key>Next : Page(Forward) \n\ + Shift<Btn4Down>,<Btn4Up>: Page(Line,-1) \n\ + Shift<Btn5Down>,<Btn5Up>: Page(Line,1) \n\ + Ctrl<Btn4Down>,<Btn4Up>: Page(Back) \n\ + Ctrl<Btn5Down>,<Btn5Up>: Page(Forward) \n\ + None<Btn4Down>,<Btn4Up>: Page(Line,-5) \n\ + None<Btn5Down>,<Btn5Up>: Page(Line,5) + +*manualBrowser*manualPage.translations: #override \ + Ctrl<Btn1Down>: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl<Btn2Down>: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift<Btn2Down>,<Btn2Up>:GotoPage(Directory)\n\ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>r: RemoveThisManpage() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>d: GotoPage(Directory) \n\ + Ctrl<Key>m: GotoPage(ManualPage) \n\ + Ctrl<Key>p: PrintThisManpage() \n\ + Ctrl<Key>v: ShowVersion() \n\ + <Key>Prior: Page(Back) \n\ + <Key>Next : Page(Forward) \n\ + Shift<Btn4Down>,<Btn4Up>: Page(Line,-1) \n\ + Shift<Btn5Down>,<Btn5Up>: Page(Line,1) \n\ + Ctrl<Btn4Down>,<Btn4Up>: Page(Back) \n\ + Ctrl<Btn5Down>,<Btn5Up>: Page(Forward) \n\ + None<Btn4Down>,<Btn4Up>: Page(Line,-5) \n\ + None<Btn5Down>,<Btn5Up>: Page(Line,5) \n\ + Ctrl<Key>s: PopupSearch() + +!*manualBrowser*directory.background: Grey80 +*manualBrowser*directory.translations: #override \ + Ctrl<Btn1Down>: \ + XawPositionSimpleMenu(optionMenu) \ + MenuPopup(optionMenu) \n\ + Ctrl<Btn2Down>: \ + XawPositionSimpleMenu(sectionMenu) \ + MenuPopup(sectionMenu) \n\ + Shift<Btn2Down>,<Btn2Up>: GotoPage(Manpage) \n\ + Ctrl<Key>q: Quit() \n\ + Ctrl<Key>c: Quit() \n\ + Ctrl<Key>r: RemoveThisManpage() \n\ + Ctrl<Key>n: CreateNewManpage() \n\ + Ctrl<Key>h: PopupHelp() \n\ + Ctrl<Key>d: GotoPage(Directory) \n\ + Ctrl<Key>m: GotoPage(ManualPage) \n\ + Ctrl<Key>v: ShowVersion() \n\ + Ctrl<Key>s: PopupSearch() + +*manualBrowser*search*manualPage.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Manpage) reset() + +*manualBrowser*search*apropos.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Apropos) reset() + +*manualBrowser*search*cancel*translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Cancel) reset() + +*manualBrowser*search*value*translations: #override \ + <Key>Return: Search(Manpage) \n\ + Ctrl<Key>m: Search(Manpage) + +*topBox*search*manualPage.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Manpage, Open) reset() + +*topBox*search*apropos.translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Apropos, Open) reset() + +*topBox*search*cancel*translations: #augment \ + <Btn1Down>,<Btn1Up>: Search(Cancel, Open) reset() + +*topBox*search*value*translations: #override \ + <Key>Return: Search(Manpage, Open) \n\ + Ctrl<Key>m: Search(Manpage, Open) + +*manualBrowser*likeToSave*yes.translations: #override \ + <Btn1Down>,<Btn1Up>: SaveFormattedPage(Save) reset() \n\ + <Key>y: SaveFormattedPage(Save) \n\ + <Key>n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*no.translations: #override \ + <Btn1Down>,<Btn1Up>: SaveFormattedPage(Cancel) reset() \n\ + <Key>y: SaveFormattedPage(Save) \n\ + <Key>n: SaveFormattedPage(Cancel) + +*manualBrowser*likeToSave*translations: #override \ + <Key>y: SaveFormattedPage(Save) \n\ + <Key>n: SaveFormattedPage(Cancel) + +*helpButton.translations: #augment \ + <Btn1Down>,<Btn1Up>: PopupHelp() reset() + +*quitButton.translations: #augment \ + <Btn1Down>,<Btn1Up>: Quit() reset() + +*manpageButton.translations: #augment \ + <Btn1Down>,<Btn1Up>: CreateNewManpage() reset() + +! Use "white" as background for printing +*printshell*background: white + +! Print dialog +*printdialogshell*geometry: 600x120 +*printdialogshell*title: Print +*printdialogshell*main*ok.fromVert: innerform +*printdialogshell*main*ok.label: Print +*printdialogshell*main*ok.tip: Print +*printdialogshell*main*setup.fromHoriz: ok +*printdialogshell*main*setup.fromVert: innerform +*printdialogshell*main*setup.label: Setup... +*printdialogshell*main*setup.tip: Configure print job options (page size, orientation, etc.) +*printdialogshell*main*cancel.fromHoriz: setup +*printdialogshell*main*cancel.fromVert: innerform +*printdialogshell*main*cancel.label: Cancel +*printdialogshell*main*cancel.tip: Cancel printing +*printdialogshell*main*desclabel.label: Printer Description: +*printdialogshell*main*desclabel.tip: Short description of printer +*printdialogshell*main*desc.fromHoriz: desclabel +*printdialogshell*main*desc.tip: Short description of printer +*printdialogshell*main*info.fromHoriz: desc +*printdialogshell*main*info.label: Printer info... +*printdialogshell*main*info.tip: Display additional information about this printer +*printdialogshell*main*namelabel.fromVert: desclabel +*printdialogshell*main*namelabel.label: Printer Name: +*printdialogshell*main*namelabel.tip: Name of selected printer +*printdialogshell*main*name.fromHoriz: namelabel +*printdialogshell*main*name.fromVert: desclabel +*printdialogshell*main*name.tip: Name of selected printer +*printdialogshell*main*selectprinter.fromHoriz: name +*printdialogshell*main*selectprinter.fromVert: desclabel +*printdialogshell*main*selectprinter.label: Select Printer... +*printdialogshell*main*selectprinter.label: Select Printer... +*printdialogshell*main*selectprinter.tip: Select a different printer +*printdialogshell*main*filenamelabel.fromVert: namelabel +*printdialogshell*main*filenamelabel.label: File Name: +*printdialogshell*main*filenamelabel.tip: File where the output should be stored +*printdialogshell*main*filename.fromHoriz: filenamelabel +*printdialogshell*main*filename.fromVert: namelabel +*printdialogshell*main*filename.tip: File where the output should be stored +*printdialogshell*main*selectfile.fromHoriz: filename +*printdialogshell*main*selectfile.fromVert: namelabel +*printdialogshell*main*selectfile.label: Select File... +*printdialogshell*main*selectfile.tip: Select file where the output should be stored +*printdialogshell*main*printtoprinter.fromVert: filenamelabel +*printdialogshell*main*printtoprinter.label: Print to Printer +*printdialogshell*main*printtoprinter.tip: Send print job to printer +*printdialogshell*main*printtofile.fromVert: filenamelabel +*printdialogshell*main*printtofile.fromHoriz: printtoprinter +*printdialogshell*main*printtofile.label: Print to File +*printdialogshell*main*printtofile.tip: Save print job in a file + +! Print job options dialog +*printdialogshell*setup*geometry: 600x400 +*printdialogshell*setup*title: Print: Print job options +*printdialogshell*setup*ok.fromVert: list +*printdialogshell*setup*ok.label: OK +*printdialogshell*setup*ok.tip: Commit changes +*printdialogshell*setup*cancel.fromHoriz: ok +*printdialogshell*setup*cancel.fromVert: list +*printdialogshell*setup*cancel.label: Cancel +*printdialogshell*setup*cancel.tip: Cancel and reset to defaults +*printdialogshell*setup*paperlist.tip: Select paper size +*printdialogshell*setup*resolutionlist.fromHoriz: paperlist +*printdialogshell*setup*resolutionlist.tip: Select page resolution +*printdialogshell*setup*orientationlist.fromHoriz: resolutionlist +*printdialogshell*setup*orientationlist.tip: Select page orientation +*printdialogshell*setup*plexlist.fromHoriz: orientationlist +*printdialogshell*setup*plexlist.tip: Select page plex mode (simplex, duplex, etc.) +*printdialogshell*setup*jobcopieslabel.fromVert: paperlist +*printdialogshell*setup*jobcopieslabel.tip: Set number of job copies +*printdialogshell*setup*jobcopieslabel.label: Job Copies: +*printdialogshell*setup*jobcopies.fromHoriz: jobcopieslabel +*printdialogshell*setup*jobcopies.fromVert: paperlist +*printdialogshell*setup*jobcopies.tip: Set number of job copies + +! Printer selection +*printdialogshell*printerselection*geometry: 400x150 +*printdialogshell*printerselection*title: Print: Select printer +*printdialogshell*printerselection*ok.fromVert: list +*printdialogshell*printerselection*ok.label: OK +*printdialogshell*printerselection*ok.tip: Switch printer +*printdialogshell*printerselection*cancel.fromHoriz: ok +*printdialogshell*printerselection*cancel.fromVert: list +*printdialogshell*printerselection*cancel.label: Cancel +*printdialogshell*printerselection*cancel.tip: Cancel printer selection +*printdialogshell*printerselection*list.tip: Select printer name from list + +! Select job file +*printdialogshell*selectfile*geometry: 400x80 +*printdialogshell*selectfile*title: Print: Select job file +*printdialogshell*selectfile*dialog.label: Select Filename: + +! EOF. @@ -121,13 +121,7 @@ MakeTopBox(void) /* add WM_COMMAND property */ XSetCommand(XtDisplay(top), XtWindow(top), saved_argv, saved_argc); - man_globals = (ManpageGlobals*) XtMalloc( (Cardinal) sizeof(ManpageGlobals)); - man_globals->label = NULL; - man_globals->search_widget = NULL; - man_globals->manpagewidgets.directory = NULL; - man_globals->manpagewidgets.manpage = NULL; - man_globals->manpagewidgets.box = NULL; - man_globals->current_directory = 0; + man_globals = (ManpageGlobals*) XtCalloc(ONE, (Cardinal) sizeof(ManpageGlobals)); MakeSearchWidget(man_globals, top); MakeSaveWidgets(man_globals, top); @@ -283,6 +277,11 @@ Boolean full_instance) XtSetValues(man_globals->both_screens_entry, arglist, ONE); } +#ifdef INCLUDE_XPRINT_SUPPORT + XtSetArg(arglist[0], XtNsensitive, True); + XtSetValues(man_globals->print_entry, arglist, ONE); +#endif /* INCLUDE_XPRINT_SUPPORT */ + man_globals->label = XtCreateManagedWidget("manualTitle", labelWidgetClass, hpane, NULL, (Cardinal) 0); @@ -435,6 +434,9 @@ CreateOptionMenu(ManpageGlobals * man_globals, Widget parent) BOTH_SCREENS, REMOVE_MANPAGE, OPEN_MANPAGE, +#ifdef INCLUDE_XPRINT_SUPPORT + PRINT_MANPAGE, +#endif /* INCLUDE_XPRINT_SUPPORT */ SHOW_VERSION, QUIT }; @@ -469,16 +471,33 @@ CreateOptionMenu(ManpageGlobals * man_globals, Widget parent) case 6: man_globals->open_entry = entry; break; +#ifdef INCLUDE_XPRINT_SUPPORT + case 7: + man_globals->print_entry = entry; + break; + case 8: + man_globals->version_entry = entry; + break; + case 9: + man_globals->quit_entry = entry; + break; +#else /* !INCLUDE_XPRINT_SUPPORT */ case 7: man_globals->version_entry = entry; break; case 8: man_globals->quit_entry = entry; break; +#endif /* !INCLUDE_XPRINT_SUPPORT */ default: + Error(("CreateOptionMenu: Unknown id=%d\n", i)); break; } } + +#ifdef INCLUDE_XPRINT_SUPPORT + XtVaSetValues(man_globals->print_entry, XtNsensitive, FALSE, NULL); +#endif /* INCLUDE_XPRINT_SUPPORT */ } /* Function Name: CreateSectionMenu @@ -67,7 +67,11 @@ from the X Consortium. /* Names of the menu buttons */ +#ifdef INCLUDE_XPRINT_SUPPORT +#define NUM_OPTIONS 10 /* Number of menu options. */ +#else /* !INCLUDE_XPRINT_SUPPORT */ #define NUM_OPTIONS 9 /* Number of menu options. */ +#endif /* !INCLUDE_XPRINT_SUPPORT */ #define DIRECTORY "displayDirectory" #define MANPAGE "displayManualPage" @@ -76,6 +80,9 @@ from the X Consortium. #define BOTH_SCREENS "showBothScreens" #define REMOVE_MANPAGE "removeThisManpage" #define OPEN_MANPAGE "openNewManpage" +#ifdef INCLUDE_XPRINT_SUPPORT +#define PRINT_MANPAGE "printManualPage" +#endif /* INCLUDE_XPRINT_SUPPORT */ #define SHOW_VERSION "showVersion" #define QUIT "quit" @@ -40,6 +40,10 @@ from the X Consortium. #include <sys/stat.h> #include "globals.h" #include "vendor.h" +#ifdef INCLUDE_XPRINT_SUPPORT +#include "printdialog.h" +#include "print.h" +#endif /* INCLUDE_XPRINT_SUPPORT */ static void PutUpManpage(ManpageGlobals * man_globals, FILE * file); static void ToggleBothShownState(ManpageGlobals * man_globals); @@ -79,6 +83,10 @@ OptionCallback(Widget w, XtPointer pointer, XtPointer junk) RemoveThisManpage(XtParent(w), NULL, NULL, NULL); else if ( w == man_globals->open_entry) /* Open new manpage */ CreateNewManpage(XtParent(w), NULL, NULL, NULL); +#ifdef INCLUDE_XPRINT_SUPPORT + else if ( w == man_globals->print_entry) /* Print current manpage */ + PrintThisManpage(XtParent(w), NULL, NULL, NULL); +#endif /* INCLUDE_XPRINT_SUPPORT */ else if ( w == man_globals->version_entry) /* Get version */ ShowVersion(XtParent(w), NULL, NULL, NULL); else if ( w == man_globals->quit_entry) /* Quit. */ @@ -215,7 +223,9 @@ DirectoryHandler(Widget w, XtPointer global_pointer, XtPointer ret_val) file = FindManualFile(man_globals, man_globals->current_directory, ret_struct->list_index); PutUpManpage(man_globals, file); - fclose(file); + if ((file != NULL) && (file != man_globals->curr_file)) { + fclose(file); + } } /* Function Name: DirPopupCallback @@ -431,8 +441,7 @@ GotoPage(Widget w, XEvent * event, String * params, Cardinal * num_params) void Quit(Widget w, XEvent * event, String * params, Cardinal * num_params) { - XCloseDisplay(XtDisplay(w)); - exit(0); + XtAppSetExitFlag(XtWidgetToApplicationContext(w)); } /* Function Name: PopupHelp @@ -589,9 +598,113 @@ Search(Widget w, XEvent * event, String * params, Cardinal * num_params) else { PutUpManpage(man_globals, file); } - if (file != NULL) - fclose(file); + if ((file != NULL) && (file != man_globals->curr_file)) { + fclose(file); + } +} + +#ifdef INCLUDE_XPRINT_SUPPORT +static void +printshellDestroyXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + ManpageGlobals *mg = GetGlobals(w); + XawPrintDialogClosePrinterConnection(mg->printdialog, False); +} + +static void +printOKXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + XawPrintDialogCallbackStruct *pdcs = (XawPrintDialogCallbackStruct *)callData; + Cardinal n; + Arg args[2]; + ManpageGlobals *mg = GetGlobals(w); + Widget topwindow = mg->This_Manpage; + FILE *file; + + Log(("printOKXtProc: OK.\n")); + + /* Get file object */ + n = 0; + XtSetArg(args[n], XtNfile, &file); n++; + XtGetValues(mg->manpagewidgets.manpage, args, n); + Assertion(file != NULL, (("printOKXtProc: file == NULL.\n"))); + + DoPrintManpage("Xman", + file, topwindow, + pdcs->pdpy, pdcs->pcontext, printshellDestroyXtProc, + mg->manpage_title, + pdcs->printToFile?pdcs->printToFileName:NULL); + + XtPopdown(mg->printdialog_shell); +} + +static void +printCancelXtProc(Widget w, XtPointer client_data, XtPointer callData) +{ + ManpageGlobals * mg = GetGlobals(w); + + Log(("printCancelXtProc: cancel.\n")); + XtPopdown(mg->printdialog_shell); + + Log(("destroying print dialog shell...\n")); + XtDestroyWidget(mg->printdialog_shell); + mg->printdialog_shell = NULL; + mg->printdialog = NULL; + Log(("... done\n")); +} + +/* Function Name: PrintThisManpage + * Description: Print the current manual page. + * Arguments: mg - manpage globals + * Returns: none. + */ + +/*ARGSUSED*/ +void +PrintThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params) +{ + ManpageGlobals *mg = GetGlobals(w); + Dimension width, height; + Position x, y; + Widget parent = mg->This_Manpage; + Widget topwindow = mg->This_Manpage; + Log(("print!\n")); + + if (!mg->printdialog) { + int n; + Arg args[20]; + + n = 0; + XtSetArg(args[n], XtNallowShellResize, True); n++; + mg->printdialog_shell = XtCreatePopupShell("printdialogshell", + transientShellWidgetClass, + topwindow, args, n); + n = 0; + mg->printdialog = XtCreateManagedWidget("printdialog", printDialogWidgetClass, + mg->printdialog_shell, args, n); + XtAddCallback(mg->printdialog, XawNOkCallback, printOKXtProc, NULL); + XtAddCallback(mg->printdialog, XawNCancelCallback, printCancelXtProc, NULL); + + XtRealizeWidget(mg->printdialog_shell); + } + + /* Center dialog */ + XtVaGetValues(mg->printdialog_shell, + XtNwidth, &width, + XtNheight, &height, + NULL); + + x = (Position)(XWidthOfScreen( XtScreen(parent)) - width) / 2; + y = (Position)(XHeightOfScreen(XtScreen(parent)) - height) / 3; + + XtVaSetValues(mg->printdialog_shell, + XtNx, x, + XtNy, y, + NULL); + + XtPopup(mg->printdialog_shell, XtGrabNonexclusive); } +#endif /* INCLUDE_XPRINT_SUPPORT */ /* Function Name: ShowVersion * Description: Show current version. @@ -41,7 +41,7 @@ from the X Consortium. #include <X11/Xaw/Cardinals.h> #endif /* ZERO */ -#if !defined(lint) && !defined(SABER) && 0 +#if !defined(lint) && !defined(SABER) static char version[] = XMAN_VERSION; /* via strings. */ #endif @@ -125,6 +125,9 @@ XtActionsRec xman_actions[] = { {"CreateNewManpage", CreateNewManpage}, {"RemoveThisManpage", RemoveThisManpage}, {"SaveFormattedPage", SaveFormattedPage}, +#ifdef INCLUDE_XPRINT_SUPPORT + {"PrintThisManpage", PrintThisManpage}, +#endif /* INCLUDE_XPRINT_SUPPORT */ {"ShowVersion", ShowVersion}, }; @@ -168,7 +171,7 @@ int main(int argc, char ** argv) if ( (argc != 1) || (resources.show_help_syntax) ) { ArgError(argc, argv); - exit(1); + return EXIT_FAILURE; } XtAppAddActions(app_con, xman_actions, XtNumber(xman_actions)); @@ -215,7 +218,7 @@ int main(int argc, char ** argv) XtAppMainLoop(app_con); - exit(0); + return EXIT_SUCCESS; } /* Function Name: ArgError @@ -288,7 +291,7 @@ AdjustDefResources(void) if (!(my_resources[i].default_addr = malloc(strlen(xwinhome) + sizeof("/lib/X11/xman.help")))) { fprintf(stderr, "malloc failure\n"); - exit(1); + exit(EXIT_FAILURE); } sprintf(my_resources[i].default_addr, "%s/lib/X11/xman.help", xwinhome); } @@ -1,4 +1,5 @@ /* $XConsortium: man.c,v 1.30 94/04/17 20:43:56 rws Exp $ */ +/* $XdotOrg: xc/programs/xman/man.c,v 1.3 2004/05/22 19:20:06 alanc Exp $ */ /* Copyright (c) 1987, 1988 X Consortium @@ -28,7 +29,7 @@ other dealings in this Software without prior written authorization from the X Consortium. */ -/* $XFree86: xc/programs/xman/man.c,v 1.7 2002/08/05 01:47:34 torrey Exp $ */ +/* $XFree86: xc/programs/xman/man.c,v 1.8 2003/04/09 20:31:31 herrb Exp $ */ #include "globals.h" @@ -285,7 +286,7 @@ SortList(SectionList ** list) /* Function Name: ReadMandescFile * Description: Reads the mandesc file, and adds more sections as - * nescessary. + * necessary. * Arguments: path - path name if the current search directory. * section_list - pointer to the list of sections. * Returns: TRUE in we should use default sections @@ -300,7 +301,7 @@ ReadMandescFile(SectionList ** section_list, char * path) Boolean use_defaults = TRUE; char *cp; - sprintf(mandesc_file, "%s/%s", path, MANDESC); + snprintf(mandesc_file, sizeof(mandesc_file), "%s/%s", path, MANDESC); if ( (descfile = fopen(mandesc_file, "r")) != NULL) { while ( fgets(string, BUFSIZ, descfile) != NULL) { string[strlen(string)-1] = '\0'; /* Strip off the CR. */ @@ -328,10 +329,10 @@ ReadMandescFile(SectionList ** section_list, char * path) } else AddNewSection(section_list, path, local_file, cp, MNULL); } else { - sprintf(local_file, "%s%c", MAN, string[0]); + snprintf(local_file, sizeof(local_file), "%s%c", MAN, string[0]); AddNewSection(section_list, path, local_file, (string + 1), FALSE ); #ifdef SEARCHOTHER - sprintf(local_file, "%s%c", SEARCHOTHER, string[0]); + snprintf(local_file, sizeof(local_file), "%s%c", SEARCHOTHER, string[0]); AddNewSection(section_list, path, local_file, (string + 1), FALSE); #endif } @@ -376,7 +377,7 @@ int flags) local_list->next = NULL; local_list->label = StrAlloc(label); - sprintf(full_path, "%s/%s", path, file); + snprintf(full_path, sizeof(full_path), "%s/%s", path, file); local_list->directory = StrAlloc(full_path); local_list->flags = flags; } @@ -395,11 +396,11 @@ AddToCurrentSection(Manual * local_manual, char * path) char temp_path[BUFSIZ]; #if defined(__OpenBSD__) || defined(__NetBSD__) - sprintf(temp_path, "%s/%s", path, MACHINE); + snprintf(temp_path, sizeof(temp_path), "%s/%s", path, MACHINE); ReadCurrentSection(local_manual, temp_path); #endif ReadCurrentSection(local_manual, path); - sprintf(temp_path, "%s.%s", path, COMPRESSION_EXTENSION); + snprintf(temp_path, sizeof(temp_path), "%s.%s", path, COMPRESSION_EXTENSION); ReadCurrentSection(local_manual, temp_path); } @@ -425,7 +426,7 @@ ReadCurrentSection(Manual * local_manual, char * path) if((dir = opendir(path)) == NULL) { #ifdef DEBUG - sprintf(error_buf,"Can't open directory %s", path); + snprintf(error_buf, sizeof(error_buf), "Can't open directory %s", path); PopupWarning(NULL, error_buf); #endif /* DEBUG */ return; @@ -468,7 +469,7 @@ ReadCurrentSection(Manual * local_manual, char * path) nalloc * sizeof(char *)); } - sprintf(full_name, "%s/%s", path, name); + snprintf(full_name, sizeof(full_name), "%s/%s", path, name); /* * Remove the compression extension from the entry name. */ @@ -484,6 +485,12 @@ ReadCurrentSection(Manual * local_manual, char * path) else if (streq(ptr + 1, GZIP_EXTENSION)) *ptr = '\0'; #endif +#ifdef IGNORE_EXTENSION + /* skip files with specified extension - they're not real man pages */ + else if (streq(ptr + 1, IGNORE_EXTENSION)) { + continue; + } +#endif /* IGNORE_EXTENSION */ } local_manual->entries[nentries] = StrAlloc(full_name); local_manual->entries_less_paths[nentries] = @@ -1,4 +1,5 @@ /* $XConsortium: man.h,v 1.31 94/12/16 21:36:53 gildea Exp $ */ +/* $XdotOrg: xc/programs/xman/man.h,v 1.8 2004/09/02 08:40:33 kem Exp $ */ /* Copyright (c) 1987, 1988 X Consortium @@ -28,7 +29,7 @@ other dealings in this Software without prior written authorization from the X Consortium. */ -/* $XFree86: xc/programs/xman/man.h,v 1.3 2000/03/03 23:16:27 dawes Exp $ */ +/* $XFree86: xc/programs/xman/man.h,v 1.4 2001/07/25 15:05:27 dawes Exp $ */ /* X toolkit header files */ @@ -42,6 +43,7 @@ from the X Consortium. /* Std system and C header files */ #include <stdio.h> +#include <limits.h> #include <X11/Xfuncs.h> #include <X11/Xos.h> @@ -71,6 +73,17 @@ from the X Consortium. #include "version.h" #include "defs.h" +/* Turn a NULL pointer string into an empty string */ +#define NULLSTR(x) (((x)!=NULL)?(x):("")) + +#define Error(x) { printf x ; exit(EXIT_FAILURE); } +#define Assertion(expr, msg) { if (!(expr)) { Error msg } } +#ifdef DEBUG +# define Log(x) { if(True) printf x; } +#else +# define Log(x) { if(False) printf x; } +#endif /* DEBUG */ + /* * Assigning values here allows the user of Bitwise Or. */ @@ -131,12 +144,19 @@ typedef struct _ManpageGlobals{ help_button, /* The help button. */ option_menu, /* The option menu. */ text_widget; /* text widget containing search string. */ - - /* Widgets (Objects really) for the command menu entries. */ - - Widget dir_entry, manpage_entry, help_entry, - search_entry, both_screens_entry, remove_entry, open_entry, - version_entry, quit_entry; + + /* Widgets (Objects really) for the command menu entries. */ + + Widget dir_entry, manpage_entry, help_entry, + search_entry, both_screens_entry, remove_entry, + open_entry, print_entry, version_entry, quit_entry; + +#ifdef INCLUDE_XPRINT_SUPPORT + /* Print objects and data */ + Widget printdialog_shell; /* Shell for the print dialog */ + Widget printdialog; /* Print dialog */ +#endif /*INCLUDE_XPRINT_SUPPORT */ + /* Misc. */ char manpage_title[80]; /* The label to use for the current manpage. */ @@ -146,15 +166,17 @@ typedef struct _ManpageGlobals{ page from. */ Boolean compress; /* Compress file on save? */ Boolean gzip; /* Gzip file on save? */ + Boolean deletetempfile; /* Need to delete tempfile when done? */ char ** section_name; /* The name of each of the sections */ ManPageWidgets manpagewidgets; /* The manpage widgets. */ - /* Things to remember when cleaning up whne killing manpage. */ + /* Things to remember when cleaning up when killing manpage. */ Widget This_Manpage; /* a pointer to the root of this manpage. */ + FILE *curr_file; /* Current file shown in manpage widget */ } ManpageGlobals; @@ -163,7 +185,7 @@ typedef struct _ManpageGlobals{ typedef struct _Xman_Resources { XmanFonts fonts; /* The fonts used for the man pages. */ XmanCursors cursors; /* The cursors for xman. */ - Boolean show_help_syntax; /* True of syntax message should be dumped to + Boolean show_help_syntax; /* True if syntax message should be dumped to stdout. */ Boolean both_shown_initial; /* The initial state of the manual pages show two screens or only one. */ @@ -219,6 +241,9 @@ void Quit(Widget w, XEvent * event, String * params, Cardinal * num_params); void RemoveThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params); void SaveFormattedPage(Widget w, XEvent * event, String * params, Cardinal * num_params); void Search(Widget w, XEvent * event, String * params, Cardinal * num_params); +#ifdef INCLUDE_XPRINT_SUPPORT +void PrintThisManpage(Widget w, XEvent * event, String * params, Cardinal * num_params); +#endif /* INCLUDE_XPRINT_SUPPORT */ void ShowVersion(Widget w, XEvent * event, String * params, Cardinal * num_params); /* help.c */ @@ -231,7 +256,6 @@ Bool ReadManConfig(char manpath[]); int Man(void); /* misc.c */ -FILE * DoSearch(ManpageGlobals * man_globals, int type); FILE * FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num); ManpageGlobals * GetGlobals(Widget w); void AddCursor(Widget w, Cursor cursor); @@ -246,6 +270,7 @@ void ParseEntry(char *entry, char *path, char *sect, char *page); FILE * Format(ManpageGlobals * man_globals, char * entry); /* search */ +FILE * DoSearch(ManpageGlobals * man_globals, int type); void MakeSearchWidget(ManpageGlobals * man_globals, Widget parent); /* tkfunctions.c */ @@ -1,4 +1,5 @@ /* $XConsortium: misc.c,v 1.31 94/12/16 21:36:53 gildea Exp $ */ +/* $XdotOrg: xc/programs/xman/misc.c,v 1.6 2004/09/02 08:40:33 kem Exp $ */ /* Copyright (c) 1987, 1988 X Consortium @@ -28,7 +29,7 @@ other dealings in this Software without prior written authorization from the X Consortium. */ -/* $XFree86: xc/programs/xman/misc.c,v 1.9 2003/05/27 22:27:08 tsi Exp $ */ +/* $XFree86: xc/programs/xman/misc.c,v 1.10 2003/08/02 17:35:48 herrb Exp $ */ /* * xman - X window system manual page display program. @@ -94,7 +95,7 @@ PopupWarning(ManpageGlobals * man_globals, char * string) char buffer[BUFSIZ]; Boolean hasPosition; - sprintf( buffer, "Xman Warning: %s", string); + snprintf( buffer, sizeof(buffer), "Xman Warning: %s", string); hasPosition = FALSE; if (top) { @@ -137,7 +138,7 @@ void PrintError(char * string) { fprintf(stderr,"Xman Error: %s\n",string); - exit(1); + exit(EXIT_FAILURE); } /* Function Name: OpenFile @@ -152,8 +153,15 @@ OpenFile(ManpageGlobals * man_globals, FILE * file) { Arg arglist[1]; Cardinal num_args = 0; + + if (man_globals->curr_file) { +#if 0 /* Ownership rules need to be fixed first */ + fclose(man_globals->curr_file); +#endif + } + man_globals->curr_file = file; - XtSetArg(arglist[num_args], XtNfile, file); num_args++; + XtSetArg(arglist[num_args], XtNfile, man_globals->curr_file); num_args++; XtSetValues(man_globals->manpagewidgets.manpage, arglist, num_args); } @@ -168,7 +176,7 @@ OpenFile(ManpageGlobals * man_globals, FILE * file) * NOTES: * * If there is a uncompressed section it will look there for uncompresed - * manual pages first and then for individually comressed file in the + * manual pages first and then for individually compressed file in the * uncompressed section. * * If there is a compressed directory then it will also look there for @@ -190,7 +198,8 @@ FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num) #endif temp = CreateManpageName(entry, 0, 0); - sprintf(man_globals->manpage_title, "The current manual page is: %s.", temp); + snprintf(man_globals->manpage_title, sizeof(man_globals->manpage_title), + "The current manual page is: %s.", temp); XtFree(temp); ParseEntry(entry, path, section, page); @@ -200,13 +209,14 @@ FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num) */ #if defined(__OpenBSD__) || defined(__NetBSD__) /* look in machine subdir first */ - sprintf(filename, "%s/%s%s/%s/%s", path, CAT, + snprintf(filename, sizeof(filename), "%s/%s%s/%s/%s", path, CAT, section + len_cat, MACHINE, page); if ( (file = fopen(filename,"r")) != NULL) return(file); #endif - sprintf(filename, "%s/%s%s/%s", path, CAT, section + len_cat, page); + snprintf(filename, sizeof(filename), "%s/%s%s/%s", + path, CAT, section + len_cat, page); if ( (file = fopen(filename,"r")) != NULL) return(file); @@ -217,12 +227,12 @@ FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num) #if !defined(ISC) && !defined(SCO) #if defined(__OpenBSD__) || defined(__NetBSD__) /* look in machine subdir first */ - sprintf(filename, "%s/%s%s/%s/%s.%s", path, CAT, + snprintf(filename, sizeof(filename), "%s/%s%s/%s/%s.%s", path, CAT, section + len_cat, MACHINE, page, COMPRESSION_EXTENSION); if ( (file = Uncompress(man_globals, filename)) != NULL) return(file); #endif - sprintf(filename, "%s/%s%s/%s.%s", path, CAT, + snprintf(filename, sizeof(filename), "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, COMPRESSION_EXTENSION); if ( (file = Uncompress(man_globals, filename)) != NULL) return(file); @@ -230,12 +240,12 @@ FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num) else { #if defined(__OpenBSD__) || defined(__NetBSD__) /* look in machine subdir first */ - sprintf(filename, "%s/%s%s/%s/%s.%s", path, CAT, + snprintf(filename, sizeof(filename), "%s/%s%s/%s/%s.%s", path, CAT, section + len_cat, MACHINE, page, GZIP_EXTENSION); if ( (file = Uncompress(man_globals, filename)) != NULL) return(file); #endif - sprintf(filename, "%s/%s%s/%s.%s", path, CAT, + snprintf(filename, sizeof(filename), "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, GZIP_EXTENSION); if ( (file = Uncompress(man_globals, filename)) != NULL) return(file); @@ -243,7 +253,7 @@ FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num) #endif #else for(i = 0; i < strlen(COMPRESSION_EXTENSIONS); i++) { - sprintf(filename, "%s/%s%s/%s.%c", path, CAT, + snprintf(filename, sizeof(filename), "%s/%s%s/%s.%c", path, CAT, section + len_cat, page, COMPRESSION_EXTENSIONS[i]); uncompress_format = uncompress_formats[i]; #ifdef DEBUG @@ -262,8 +272,8 @@ FindManualFile(ManpageGlobals * man_globals, int section_num, int entry_num) * HP does it this way (really :-). */ - sprintf(filename, "%s/%s%s.%s/%s", path, CAT, section + len_cat, - COMPRESSION_EXTENSION, page); + snprintf(filename, sizeof(filename), "%s/%s%s.%s/%s", path, CAT, + section + len_cat, COMPRESSION_EXTENSION, page); if ( (file = Uncompress(man_globals, filename)) != NULL) return(file); /* @@ -336,8 +346,8 @@ UncompressNamed(ManpageGlobals * man_globals, char * filename, char * output, if (stat(filename, &junk) != 0) { /* Check for existance of the file. */ if (errno != ENOENT) { - sprintf(error_buf, "Error while stating file %s, errno = %d", - filename, errno); + snprintf(error_buf, sizeof(error_buf), + "Error while stating file %s, errno = %d", filename, errno); PopupWarning(man_globals, error_buf); } return(FALSE); @@ -364,17 +374,76 @@ UncompressNamed(ManpageGlobals * man_globals, char * filename, char * output, #ifdef GZIP_EXTENSION if (streq(filename + strlen(filename) - strlen(GZIP_EXTENSION), GZIP_EXTENSION)) - sprintf(cmdbuf, GUNZIP_FORMAT, filename, output); + snprintf(cmdbuf, sizeof(cmdbuf), GUNZIP_FORMAT, filename, output); else #endif - sprintf(cmdbuf, UNCOMPRESS_FORMAT, filename, output); + snprintf(cmdbuf, sizeof(cmdbuf), UNCOMPRESS_FORMAT, filename, output); + if(system(cmdbuf) == 0) /* execute search. */ + return(TRUE); + + snprintf(error_buf, sizeof(error_buf), + "Error while uncompressing, command was: %s", cmdbuf); + PopupWarning(man_globals, error_buf); + return(FALSE); +} + +#if defined(SMAN) && defined(SFORMAT) +/* Function Name: SgmlToRoffNamed + * Description: This function will attempt to find an SGML man + * page and convert it to roff format. + * Arguments: man_globals - the psuedo global info. + * filename - name of file to uncompress. + * RETURNED output - the file name output (must be an allocated string). + * Returns:; TRUE if the file was found. + */ + +#ifndef HAS_MKSTEMP +static Boolean +SgmlToRoffNamed(ManpageGlobals * man_globals, char * filename, char * output) +#else +static Boolean +SgmlToRoffNamed(ManpageGlobals * man_globals, char * filename, char * output, + FILE ** output_fd) +#endif +{ + char tmp[BUFSIZ], cmdbuf[BUFSIZ], error_buf[BUFSIZ]; + struct stat junk; +#ifdef HAS_MKSTEMP + int fd; +#endif + + if (stat(filename, &junk) != 0) { /* Check for existance of the file. */ + if (errno != ENOENT) { + snprintf(error_buf, sizeof(error_buf), + "Error while stating file %s, errno = %d", filename, errno); + PopupWarning(man_globals, error_buf); + } + return(FALSE); + } + + strcpy(tmp, MANTEMP); /* get a temp file. */ +#ifndef HAS_MKSTEMP + (void) mktemp(tmp); +#else + fd = mkstemp(tmp); + if (fd < 0) { + PopupWarning(man_globals, "Error creating a temp file"); + return FALSE; + } + *output_fd = fdopen(fd, "r"); +#endif + strcpy(output, tmp); + + snprintf(cmdbuf, sizeof(cmdbuf), "%s %s > %s", SFORMAT, filename, output); if(system(cmdbuf) == 0) /* execute search. */ return(TRUE); - sprintf(error_buf, "Error while uncompressing, command was: %s", cmdbuf); + snprintf(error_buf, sizeof(error_buf), + "Error while converting from sgml, command was: %s", cmdbuf); PopupWarning(man_globals, error_buf); return(FALSE); } +#endif /* defined (SMAN) && defined(SFORMAT) */ /* Function Name: Format * Description: This funtion formats the manual pages and interfaces @@ -397,7 +466,7 @@ Format(ManpageGlobals * man_globals, char * entry) #endif Widget manpage = man_globals->manpagewidgets.manpage; char cmdbuf[BUFSIZ], tmp[BUFSIZ], filename[BUFSIZ], error_buf[BUFSIZ]; - char path[BUFSIZ]; + char path[BUFSIZ], sect[BUFSIZ]; XEvent event; Position x,y; /* location to pop up the "would you like to save" widget. */ @@ -408,7 +477,8 @@ Format(ManpageGlobals * man_globals, char * entry) if ( !UncompressUnformatted(man_globals, entry, filename, &file) ) { #endif /* We Really could not find it, this should never happen, yea right. */ - sprintf(error_buf, "Could not open manual page, %s", entry); + snprintf(error_buf, sizeof(error_buf), + "Could not open manual page, %s", entry); PopupWarning(man_globals, error_buf); XtPopdown( XtParent(man_globals->standby) ); return(NULL); @@ -438,7 +508,7 @@ Format(ManpageGlobals * man_globals, char * entry) } else *tmp = '\0'; - sprintf(filename, "%s%s", tmp, line + 4); + snprintf(filename, sizeof(filename), "%s%s", tmp, line + 4); return (Format(man_globals, filename)); } @@ -462,14 +532,14 @@ Format(ManpageGlobals * man_globals, char * entry) #endif strcpy(man_globals->tempfile, tmp); - ParseEntry(entry, path, NULL, NULL); + ParseEntry(entry, path, sect, NULL); #ifndef HANDLE_ROFFSEQ #ifndef HAS_MKSTEMP - sprintf(cmdbuf,"cd %s ; %s %s %s > %s %s", path, TBL, + snprintf(cmdbuf, sizeof(cmdbuf), "cd %s ; %s %s %s > %s %s", path, TBL, filename, FORMAT, man_globals->tempfile, "2> /dev/null"); #else - sprintf(cmdbuf,"cd %s ; %s %s %s >> %s %s", path, TBL, + snprintf(cmdbuf, sizeof(cmdbuf), "cd %s ; %s %s %s >> %s %s", path, TBL, filename, FORMAT, man_globals->tempfile, "2> /dev/null"); #endif #else @@ -483,7 +553,7 @@ Format(ManpageGlobals * man_globals, char * entry) #endif /* HANDLE_ROFFSEQ */ if(system(cmdbuf) != 0) { /* execute search. */ - sprintf(error_buf, + snprintf(error_buf, sizeof(error_buf), "Something went wrong trying to run the command: %s", cmdbuf); PopupWarning(man_globals, error_buf); file = NULL; @@ -533,10 +603,10 @@ Format(ManpageGlobals * man_globals, char * entry) #endif } - if (man_globals->compress || man_globals->gzip) /* If the original - was compressed - then this is a tempory - file. */ + /* + * If the original was compressed or in another format, delete temporary file. + */ + if (man_globals->deletetempfile) unlink(filename); return(file); @@ -727,39 +797,45 @@ UncompressUnformatted(ManpageGlobals * man_globals, char * entry, { char path[BUFSIZ], page[BUFSIZ], section[BUFSIZ], input[BUFSIZ]; int len_cat = strlen(CAT), len_man = strlen(MAN); +#if defined(SMAN) && defined(SFORMAT) + int len_sman = strlen(SMAN); +#endif ParseEntry(entry, path, section, page); #if defined(__OpenBSD__) || defined(__NetBSD__) /* - * look for uncomressed file in machine subdir first + * look for uncompressed file in machine subdir first */ - sprintf(filename, "%s/%s%s/%s/%s", path, MAN, + snprintf(filename, BUFSIZ, "%s/%s%s/%s/%s", path, MAN, section + len_cat, MACHINE, page); if ( access( filename, R_OK ) == 0 ) { man_globals->compress = FALSE; man_globals->gzip = FALSE; - sprintf(man_globals->save_file, "%s/%s%s/%s/%s", path, - CAT, section + len_cat, MACHINE, page); + man_globals->deletetempfile = FALSE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s/%s", path, CAT, section + len_cat, MACHINE, page); return(TRUE); } /* * Then for compressed files in an uncompressed directory. */ - sprintf(input, "%s.%s", filename, COMPRESSION_EXTENSION); + snprintf(input, sizeof(input), "%s.%s", filename, COMPRESSION_EXTENSION); #ifndef HAS_MKSTEMP if ( UncompressNamed(man_globals, input, filename) ) { #else if ( UncompressNamed(man_globals, input, filename, file) ) { #endif man_globals->compress = TRUE; - sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path, - CAT, section + len_cat, page, COMPRESSION_EXTENSION); + man_globals->deletetempfile = TRUE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, + COMPRESSION_EXTENSION); return(TRUE); } #ifdef GZIP_EXTENSION else { - sprintf(input, "%s.%s", filename, GZIP_EXTENSION); + snprintf(input, sizeof(input), "%s.%s", filename, GZIP_EXTENSION); #ifndef HAS_MKSTEMP if ( UncompressNamed(man_globals, input, filename) ) { #else @@ -767,8 +843,10 @@ UncompressUnformatted(ManpageGlobals * man_globals, char * entry, #endif man_globals->compress = TRUE; man_globals->gzip = TRUE; - sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path, - CAT, section + len_cat, page, GZIP_EXTENSION); + man_globals->deletetempfile = TRUE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, + GZIP_EXTENSION); return(TRUE); } } @@ -778,33 +856,56 @@ UncompressUnformatted(ManpageGlobals * man_globals, char * entry, * Look for uncompressed file first. */ - sprintf(filename, "%s/%s%s/%s", path, MAN, section + len_man, page); + snprintf(filename, BUFSIZ, "%s/%s%s/%s", path, MAN, section + len_man, page); if ( access( filename, R_OK ) == 0 ) { man_globals->compress = FALSE; man_globals->gzip = FALSE; - sprintf(man_globals->save_file, "%s/%s%s/%s", path, - CAT, section + len_cat, page); + man_globals->deletetempfile = FALSE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s", path, CAT, section + len_cat, page); return(TRUE); } +#if defined(SMAN) && defined(SFORMAT) + /* + * Look for uncompressed sgml file next. + */ + + snprintf(input, BUFSIZ, "%s/%s%s/%s", path, SMAN, section + len_sman, page); +#ifndef HAS_MKSTEMP + if ( SgmlToRoffNamed(man_globals, input, filename) ) { +#else + if ( SgmlToRoffNamed(man_globals, input, filename, file) ) { +#endif + man_globals->compress = FALSE; + man_globals->gzip = FALSE; + man_globals->deletetempfile = TRUE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s", path, CAT, section + len_cat, page); + return(TRUE); + } +#endif + /* * Then for compressed files in an uncompressed directory. */ - sprintf(input, "%s.%s", filename, COMPRESSION_EXTENSION); + snprintf(input, sizeof(input), "%s.%s", filename, COMPRESSION_EXTENSION); #ifndef HAS_MKSTEMP if ( UncompressNamed(man_globals, input, filename) ) { #else if ( UncompressNamed(man_globals, input, filename, file) ) { #endif man_globals->compress = TRUE; - sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path, - CAT, section + len_cat, page, COMPRESSION_EXTENSION); + man_globals->deletetempfile = TRUE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, + COMPRESSION_EXTENSION); return(TRUE); } #ifdef GZIP_EXTENSION else { - sprintf(input, "%s.%s", filename, GZIP_EXTENSION); + snprintf(input, sizeof(input), "%s.%s", filename, GZIP_EXTENSION); #ifndef HAS_MKSTEMP if ( UncompressNamed(man_globals, input, filename) ) { #else @@ -812,8 +913,10 @@ UncompressUnformatted(ManpageGlobals * man_globals, char * entry, #endif man_globals->compress = TRUE; man_globals->gzip = TRUE; - sprintf(man_globals->save_file, "%s/%s%s/%s.%s", path, - CAT, section + len_cat, page, GZIP_EXTENSION); + man_globals->deletetempfile = TRUE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s/%s.%s", path, CAT, section + len_cat, page, + GZIP_EXTENSION); return(TRUE); } } @@ -822,7 +925,7 @@ UncompressUnformatted(ManpageGlobals * man_globals, char * entry, * And lastly files in a compressed directory. */ - sprintf(input, "%s/%s%s.%s/%s", path, + snprintf(input, sizeof(input), "%s/%s%s.%s/%s", path, MAN, section + len_man, COMPRESSION_EXTENSION, page); #ifndef HAS_MKSTEMP if ( UncompressNamed(man_globals, input, filename) ) { @@ -830,8 +933,10 @@ UncompressUnformatted(ManpageGlobals * man_globals, char * entry, if ( UncompressNamed(man_globals, input, filename, file) ) { #endif man_globals->compress = TRUE; - sprintf(man_globals->save_file, "%s/%s%s.%s/%s", path, - CAT, section + len_cat, COMPRESSION_EXTENSION, page); + man_globals->deletetempfile = TRUE; + snprintf(man_globals->save_file, sizeof(man_globals->save_file), + "%s/%s%s.%s/%s", path, CAT, section + len_cat, + COMPRESSION_EXTENSION, page); return(TRUE); } return(FALSE); @@ -898,7 +1003,7 @@ ChangeLabel(Widget w, char * str) */ /* Function Name: PositionCenter - * Description: This fuction positions the given widgets center + * Description: This function positions the given widgets center * in the following location. * Arguments: widget - the widget widget to postion * x,y - The location for the center of the widget @@ -973,6 +1078,15 @@ ParseEntry(char *entry, char *path, char *sect, char *page) if (c == NULL) PrintError("index failure in ParseEntry."); *c++ = '\0'; +#if defined(SFORMAT) && defined(SMAN) + /* sgmltoroff sometimes puts an extra ./ in the path to .so entries */ + if (strcmp(c, ".") == 0) { + c = rindex(temp, '/'); + if (c == NULL) + PrintError("index failure in ParseEntry."); + *c++ = '\0'; + } +#endif #if defined(__OpenBSD__) || defined(__NetBSD__) /* Skip machine subdirectory if present */ if (strcmp(c, MACHINE) == 0) { @@ -0,0 +1,377 @@ +/* + * $Xorg: print.c,v 1.1 2004/04/30 02:05:54 gisburn Exp $ + * +Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +/* Turn a NULL pointer string into an empty string */ +#define NULLSTR(x) (((x)!=NULL)?(x):("")) + +#define Error(x) { printf x ; exit(EXIT_FAILURE); } +#define Assertion(expr, msg) { if (!(expr)) { Error msg } } +#define Log(x) { if(True) printf x; } + +#include "print.h" +#include "ScrollByL.h" +#include <X11/Xaw/Form.h> +#include <X11/Xaw/Label.h> +#include <stdio.h> +#include <stdlib.h> + +static Widget +CreatePrintShell(Widget videoshell, + Screen *pscreen, + String printshell_name, + ArgList args, + Cardinal numargs) +{ + String videoname, + videoclass; + Widget pappshell, + printshell; + Display *pdpy = XDisplayOfScreen(pscreen); + int dummyc = 0; + String dummys = ""; + XtGetApplicationNameAndClass(XtDisplay(videoshell), + &videoname, &videoclass); + + /* XXX: Why is the |dummyc|&&|dummys| stuff needed here ? */ + XtDisplayInitialize(XtWidgetToApplicationContext(videoshell), pdpy, + videoname, videoclass, + NULL, 0, + &dummyc, &dummys); + + pappshell = XtVaAppCreateShell(videoname, videoclass, + applicationShellWidgetClass, + pdpy, + XtNscreen, pscreen, + NULL); + printshell = XtCreatePopupShell(printshell_name, + xawPrintShellWidgetClass, + pappshell, args, numargs); + + + /* we're mapping/unmapping at start/end page time */ + XtSetMappedWhenManaged(printshell, False); + + /* We realise the widget when we're done with building the widget tree... */ + + return printshell; +} + +typedef struct +{ + const char *programname; + Widget toplevel; + Bool isPrinting; + Widget printshell; + struct + { + Widget form; + Widget pageheaderlabel; + Widget manpage; + } content; /* content to print */ + int numpages; + Display *pdpy; + Screen *pscreen; + XPContext pcontext; + XtCallbackProc pdpyDestroyCallback; + void *printtofile_handle; + const char *jobtitle; +} AppPrintData; + +static AppPrintData apdx; +static AppPrintData *apd = &apdx; + +/* "Count" pages in a scrollByLineWidgetClass widget */ +static +long CountPages(Widget sblw) +{ + long num_pages = 0; + Cardinal n; + Arg args[3]; + int num_total_lines = 0, + num_visible_lines = 0; + + n = 0; + XtSetArg(args[n], XtNNumTotalLines, &num_total_lines); n++; + XtSetArg(args[n], XtNNumVisibleLines, &num_visible_lines); n++; + XtGetValues(sblw, args, n); + +#define DIV_ROUND_UP(a, b) (((a)+((b)-1)) / (b)) + /* scrollByLineWidgetClass's "Page(forward)" always overlaps by one + * line so we use |num_visible_lines-1| instead of |num_visible_lines| */ + num_pages = DIV_ROUND_UP(num_total_lines, num_visible_lines-1); +#undef DIV_ROUND_UP + + return num_pages; +} + +static void +PageSetupCB(Widget widget, XtPointer client_data, XtPointer call_data) +{ + Widget pshell = widget; + XawPrintShellCallbackStruct *psp = (XawPrintShellCallbackStruct *)call_data; + AppPrintData *p = (AppPrintData *)client_data; + + Log(("--> PageSetupCB\n")); + + if (!psp->last_page_in_job) { + int currpage; + char buffer[256]; + + XtVaGetValues(pshell, XawNcurrPageNumInJob, &currpage, NULL); + + sprintf(buffer, "Title: %s / Page: %d/%d", p->jobtitle, currpage, p->numpages); + XtVaSetValues(apd->content.pageheaderlabel, XtNlabel, buffer, NULL); + + /* Note: XawPrintShell's pagecount starts with '1' + * (=first page is page no. '1') */ + if (currpage > 1) { + String params[] = { "Forward" }; + Log(("pagedown %d\n", currpage)); + /* "Page(Forward)" is scrollByLineWidgetClass's way to + * move one page forward */ + XtCallActionProc(p->content.manpage, "Page", NULL, params, ONE); + } + else + { + Log(("first page\n")); + } + + if (currpage >= p->numpages) { + psp->last_page_in_job = True; + } + } +} + +static +void FinishPrinting(AppPrintData *p) +{ + /* Wait for the job to finish */ + if (p->printtofile_handle) { + if (XpuWaitForPrintFileChild(p->printtofile_handle) != XPGetDocFinished) { + fprintf(stderr, "%s: Error while printing to file.\n", apd->programname); + } + p->printtofile_handle = NULL; + } + + /* Avoid that the manpage object tries to close the |FILE *|-handle at destruction time */ + XtVaSetValues(p->content.manpage, XtNfile, NULL, NULL); + + if (p->printshell) { + XtDestroyWidget(p->printshell); + p->printshell = NULL; + } + + /* Two issues here: + * 1. The print display connection is owned by the print dialog + * To avoid any problems with that use a callback back to the main + * application which calls + * |XawPrintDialogClosePrinterConnection(w, False)| to ask the + * print dialog widget to close all print display resources and + * disown the object. + * 2. We have to use XpDestroyContext() and XtCloseDisplay() + * instead of XpuClosePrinterDisplay() to make libXt happy... + * + * Call callback... */ + (*apd->pdpyDestroyCallback)(p->toplevel, NULL, NULL); /* HACK! */ + + /* ... and then get rid of the display */ + if (p->pcontext != None) { + XpDestroyContext(p->pdpy, p->pcontext); + } + XtCloseDisplay(p->pdpy); + + p->toplevel = NULL; + p->isPrinting = False; + p->pdpy = NULL; + p->pscreen = NULL; + p->pcontext = None; +} + +static +void PrintEndJobCB(Widget pshell, XtPointer client_data, XtPointer call_data) +{ + AppPrintData *p = (AppPrintData *)client_data; + + Log(("--> PrintEndJobCB\n")); + + /* Finish printing and destroy print shell (it's legal to destroy Xt + * widgets from within it's own callbacks) */ + FinishPrinting(p); +} + +static +XFontStruct *GetPrintTextFont(Display *pdpy, const char *fontprefix, long dpi) +{ + XFontStruct *font; + char fontname[1024]; + + sprintf(fontname, "%s--*-120-%ld-%ld-*-*-iso8859-1", fontprefix, dpi, dpi); + font = XLoadQueryFont(pdpy, fontname); + if (!font) { + sprintf(fontname, "-adobe-courier-medium-r-normal--*-120-%ld-%ld-*-*-iso8859-1", dpi, dpi); + font = XLoadQueryFont(pdpy, fontname); + } + if (!font) { + sprintf(fontname, "-*-*-*-*-*-*-*-120-%ld-%ld-*-*-iso8859-1", dpi, dpi); + font = XLoadQueryFont(pdpy, fontname); + } + if (!font) + Error(("XLoadQueryFont failure.\n")); + return font; + +} + +void DoPrintManpage(const char *programname, + FILE *manpagefile, Widget toplevel, + Display *pdpy, XPContext pcontext, + XtCallbackProc pdpyDestroyCB, + const char *jobtitle, const char *toFile) +{ + long dpi = 0; + int n; + Arg args[20]; + XFontStruct *printFontNormal; + XFontStruct *printFontBold; + XFontStruct *printFontItalic; + XFontStruct *printFontSymbol; + + if (!manpagefile) { + Error(("DoPrintManpage: No FILE given.")); + } + + apd->programname = programname; + apd->pdpyDestroyCallback = pdpyDestroyCB; + + if (apd->isPrinting) { + fprintf(stderr, "%s: Already busy with printing.\n", apd->programname); + return; + } + + /* Configure the print context (paper size, title etc.) + * We must do this before creating any Xt widgets - otherwise they will + * make wrong assuptions about fonts, resultions etc. ... + */ + XpuSetJobTitle(pdpy, pcontext, jobtitle); + + /* Configuration done, set the context */ + XpSetContext(pdpy, pcontext); + + /* Get default printer resolution */ + if (XpuGetResolution(pdpy, pcontext, &dpi) != 1) { + fprintf(stderr, "%s: No default resolution for printer.\n", apd->programname); + XpuClosePrinterDisplay(pdpy, pcontext); + return; + } + + apd->toplevel = toplevel; + apd->pdpy = pdpy; + apd->pcontext = pcontext; + apd->pscreen = XpGetScreenOfContext(pdpy, pcontext); + apd->jobtitle = jobtitle; + + n = 0; + XtSetArg(args[n], XawNlayoutMode, XawPrintLAYOUTMODE_DRAWABLEAREA); n++; + apd->printshell = CreatePrintShell(toplevel, apd->pscreen, "printshell", args, n); + + n = 0; + XtSetArg(args[n], XtNresizable, True); n++; + XtSetArg(args[n], XtNright, XtChainRight); n++; + apd->content.form = XtCreateManagedWidget("form", formWidgetClass, apd->printshell, args, n); + + printFontNormal = GetPrintTextFont(pdpy, "-*-courier-medium-r-*", dpi); + printFontBold = GetPrintTextFont(pdpy, "-*-courier-bold-r-*", dpi); + printFontItalic = GetPrintTextFont(pdpy, "-*-courier-medium-o-*", dpi); + printFontSymbol = GetPrintTextFont(pdpy, "-*-symbol-*-*-*", dpi); + + n = 0; + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, NULL); n++; + XtSetArg(args[n], XtNtop, XtChainTop); n++; + XtSetArg(args[n], XtNright, XtChainRight); n++; + XtSetArg(args[n], XtNresizable, True); n++; + XtSetArg(args[n], XtNfont, printFontNormal); n++; /* fontset would be better */ + XtSetArg(args[n], XtNlabel, "Page: n/n"); n++; + XtSetArg(args[n], XtNjustify, XtJustifyRight); n++; + apd->content.pageheaderlabel = XtCreateManagedWidget("pageinfo", labelWidgetClass, apd->content.form, args, n); + + n = 0; + XtSetArg(args[n], XtNfile, manpagefile); n++; + +/* Usually I would expect that using |XtNfromVert, apd->content.pageheaderlabel| + * would be the correct way to place the text widget with the main content below + * the page header widget - but for an unknown reason this doesn not work: The + * text widget squishes itself into the bottom half of the page and only occupies + * 1/2 of the page's with... ;-(( */ +#define WORKAROUND_FOR_SOMETHING_IS_WRONG 1 +#ifdef WORKAROUND_FOR_SOMETHING_IS_WRONG + XtSetArg(args[n], XtNtop, XtChainTop); n++; + XtSetArg(args[n], XtNright, XtChainRight); n++; + XtSetArg(args[n], XtNvertDistance, (printFontNormal->ascent+printFontNormal->descent+2)*2); n++; +#else + XtSetArg(args[n], XtNfromHoriz, NULL); n++; + XtSetArg(args[n], XtNfromVert, apd->content.pageheaderlabel); n++; +#endif + + XtSetArg(args[n], XtNmanualFontNormal, printFontNormal); n++; + XtSetArg(args[n], XtNmanualFontBold, printFontBold); n++; + XtSetArg(args[n], XtNmanualFontItalic, printFontItalic); n++; + XtSetArg(args[n], XtNmanualFontSymbol, printFontSymbol); n++; + apd->content.manpage = XtCreateManagedWidget("manpage", scrollByLineWidgetClass, apd->content.form, args, n); + + XtAddCallback(apd->printshell, XawNpageSetupCallback, PageSetupCB, (XtPointer)apd); + XtAddCallback(apd->printshell, XawNendJobCallback, PrintEndJobCB, (XtPointer)apd); + + /* Realise print shell (which will set position+size of the child + * widgets based on the current page size) */ + XtRealizeWidget(apd->printshell); + + /* Count number of pages in the manpage widget */ + apd->numpages = CountPages(apd->content.manpage); + + /* Make sure that the Xt machinery is really using the right screen (assertion) */ + if (XpGetScreenOfContext(XtDisplay(apd->printshell), apd->pcontext) != XtScreen(apd->printshell)) + Error(("Widget's screen != print screen. BAD.\n")); + + apd->isPrinting = True; + + if (toFile) { + printf("%s: Printing to file '%s'...\n", apd->programname, toFile); + apd->printtofile_handle = XpuStartJobToFile(pdpy, pcontext, toFile); + if (!apd->printtofile_handle) { + perror("XpuStartJobToFile failure"); + apd->isPrinting = False; + return; + } + } + else + { + printf("%s: Printing to printer...\n", apd->programname); + XpuStartJobToSpooler(pdpy); + } +} + + @@ -0,0 +1,47 @@ +/* + * $Xorg: print.h,v 1.1 2004/04/30 02:05:54 gisburn Exp $ + * +Copyright 2004 Roland Mainz <roland.mainz@nrubsig.org> + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + * + */ + +#ifndef XMAN_PRINT_H +#define XMAN_PRINT_H 1 + +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> +#include <X11/Xaw/Print.h> +#include <X11/Xaw/Cardinals.h> +#include <X11/XprintUtil/xprintutil.h> + +/* Prototypes */ +void DoPrintManpage(const char *programname, + FILE *manpage, + Widget toplevel, + Display *pdpy, XPContext pcontext, + XtCallbackProc printDisplayDestroyCallback, + const char *jobTitle, + const char *toFile); + +#endif /* !XMAN_PRINT_H */ @@ -265,7 +265,7 @@ DoSearch(ManpageGlobals * man_globals, int type) strcpy(man_globals->manpage_title,label); ChangeLabel(man_globals->label,label); - fseek(file, 0L, 0); /* reset file to point at top. */ + fseek(file, 0L, SEEK_SET); /* reset file to point at top. */ } else { /* MANUAL SEACH */ file = DoManualSearch(man_globals, search_string); @@ -1,4 +1,5 @@ /* $XConsortium: vendor.h,v 1.12 94/04/17 20:44:00 rws Exp $ */ +/* $XdotOrg: xc/programs/xman/vendor.h,v 1.3 2004/05/22 19:20:06 alanc Exp $ */ /* Copyright (c) 1991 X Consortium @@ -28,7 +29,7 @@ other dealings in this Software without prior written authorization from the X Consortium. */ -/* $XFree86: xc/programs/xman/vendor.h,v 1.12 2003/03/26 20:43:59 tsi Exp $ */ +/* $XFree86: xc/programs/xman/vendor.h,v 1.13 2003/07/29 21:16:56 dawes Exp $ */ /* Vendor-specific definitions */ @@ -219,6 +220,16 @@ from the X Consortium. # define CAT "cat" #endif +/* Solaris has nroff man pages in "man" and sgml man pages in "sman" */ +#if defined(sun) && defined(SVR4) +# define SFORMAT "/usr/lib/sgml/sgml2roff" +# define SMAN "sman" +# undef SEARCHOTHER +# define SEARCHOTHER SMAN +# define SGMLENT_EXTENSION "ent" /* SGML entity files end in ".ent" */ +#endif + + typedef struct _SectionList { struct _SectionList * next; char * label; /* section label */ @@ -29,4 +29,4 @@ from the X Consortium. */ -#define XMAN_VERSION "Xman Version 3.1.6 - X11R6." +#define XMAN_VERSION "Xman Version 3.2.0 - X11R6.8" |