-
Notifications
You must be signed in to change notification settings - Fork 11
/
man.c
120 lines (107 loc) · 2.97 KB
/
man.c
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 <[email protected]>
*
*/
#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]);
}