1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
/*
* motif-based man page renderer
* (c) 2001 Gerd Hoffmann <gerd@kraxel.org>
*
*/
#include <stdio.h>
#include <stddef.h>
#include <X11/Xlib.h>
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/RowColumn.h>
#include <Xm/PushB.h>
#include <Xm/ScrolledW.h>
#include <Xm/SelectioB.h>
#include "RegEdit.h"
#include "man.h"
extern Display *dpy;
extern Widget app_shell;
/*----------------------------------------------------------------------*/
#define MAN_UNDEF 0
#define MAN_NORMAL 1
#define MAN_BOLD 2
#define MAN_UNDERLINE 3
static XmStringTag man_tags[] = {
NULL, NULL, "bold", "underline"
};
static void
man_destroy(Widget widget, XtPointer clientdata, XtPointer call_data)
{
XtDestroyWidget(clientdata);
}
void
man(char *page)
{
Widget dlg,view,label;
XmString xmpage,xmchunk;
char line[1024],chunk[256];
int s,d,cur,last;
FILE *fp;
/* build dialog */
dlg = XmCreatePromptDialog(app_shell,"man",NULL,0);
XmdRegisterEditres(XtParent(dlg));
XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_SELECTION_LABEL));
XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_HELP_BUTTON));
XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_CANCEL_BUTTON));
XtUnmanageChild(XmSelectionBoxGetChild(dlg,XmDIALOG_TEXT));
XtAddCallback(dlg,XmNokCallback,man_destroy,dlg);
view = XmCreateScrolledWindow(dlg,"view",NULL,0);
XtManageChild(view);
label = XtVaCreateManagedWidget("label", xmLabelWidgetClass,view, NULL);
XtManageChild(dlg);
/* fetch page and render into XmString */
sprintf(line,"man %s 2>/dev/null",page);
fp = popen(line,"r");
xmpage = XmStringGenerate("", NULL, XmMULTIBYTE_TEXT, NULL);
while (NULL != fgets(line,sizeof(line)-1,fp)) {
last = MAN_UNDEF;
for (s = 0, d = 0; line[s] != '\0';) {
/* check current char */
cur = MAN_NORMAL;
if (line[s+1] == '\010' && line[s] == line[s+2])
cur = MAN_BOLD;
if (line[s] == '_' && line[s+1] == '\010')
cur = MAN_UNDERLINE;
/* add chunk if completed */
if (MAN_UNDEF != last && cur != last) {
xmchunk = XmStringGenerate(chunk,NULL,XmMULTIBYTE_TEXT,
man_tags[last]);
xmpage = XmStringConcatAndFree(xmpage,xmchunk);
d = 0;
}
/* add char to chunk */
switch (cur) {
case MAN_BOLD:
case MAN_UNDERLINE:
s += 2;
case MAN_NORMAL:
chunk[d++] = line[s++];
break;
}
chunk[d] = '\0';
last = cur;
}
/* add last chunk for line */
xmchunk = XmStringGenerate(chunk, NULL, XmMULTIBYTE_TEXT,
man_tags[last]);
xmpage = XmStringConcatAndFree(xmpage,xmchunk);
}
XtVaSetValues(label,XmNlabelString,xmpage,NULL);
XmStringFree(xmpage);
fclose(fp);
}
void
man_cb(Widget widget, XtPointer clientdata, XtPointer call_data)
{
char *page = clientdata;
man(page);
}
void
man_action(Widget widget, XEvent *event,
String *params, Cardinal *num_params)
{
if (*num_params > 0)
man(params[0]);
}
|