/* * motif-based man page renderer * (c) 2001 Gerd Knorr * */ #include #include #include #include #include #include #include #include #include #include #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]); }