/********************** modified from myfont.c *******************/ /********************* to test the use of XmScrolledList *********/ #include #include #include #ifdef SYS_DIR #include #else #ifdef NDIR #include #else #include #endif #endif #include #include #include #include #include #include #include #include #include void main(); Widget MyCreateMain(Widget ); Widget SelectedFontSample(Widget ); Widget MyHelpDialog(Widget,int ); Widget slist; Widget command_window; //Widget swindow; static int call_back_signal = 0; void FontSelectedCB(Widget,caddr_t,caddr_t); void CloseCB(Widget,caddr_t,caddr_t); void HelpCB(Widget,int,caddr_t); void QuitCB(Widget,caddr_t,caddr_t); void ListSelectCB(Widget,caddr_t,XmListCallbackStruct *); void ListActionCB(Widget,caddr_t,caddr_t); void CommandWindowInputCB(Widget,caddr_t,caddr_t); void MenuCommandCB(Widget,caddr_t,caddr_t); void ActiveCB(Widget,caddr_t,caddr_t); #define MAX_ARGS 20 #define MENU_DISPLAY_POSITION 201 #define MENU_NEXT_POSITION 202 typedef struct { char *fontpath; }ApplicationData,*ApplicationDataPtr; class ManPath; class SubDir; class ManItem; class ManPath { public: ManPath* next; char * alias; char * man_path; SubDir* sub_dir[11]; public: ManPath(char * path_name); ~ManPath(); LoadManPath(char *); int GetSize(char c); int GetItems(char c, ManItem *buffer[]); }; class SubDir { public: ManPath *man_path; int buffer_length; int count; ManItem **item_list; public: SubDir(ManPath *); ~SubDir(); void AddItem(char* name); int GetSize(); int GetItems(ManItem *buffer[]); }; class ManItem { public: SubDir *sub_dir; char *name; public: ManItem(SubDir *, char* name); ~ManItem(); }; void InitData(); static void attach (char *dest, const char *dirname, const char *name); static int subdir_translate_c_to_n(char c); static int ManItemComp(ManItem ** a,ManItem ** b); static int ItemMatch(char *); static void active_man_page(ManItem *); ManPath * man_paths; ManItem ** item_list; int item_list_length; int item_list_count; ApplicationData AppData; #define XtNfontPath "fontPath" #define XtCFontPath "FontPath" static XtResource resources[] = { { XtNfontPath,XtCFontPath,XmRString,sizeof(String), XtOffset(ApplicationDataPtr,fontpath), //XmRString,"/usr/lib/X11/fonts/misc" XmRString,"/home/wxk/fonts" } }; static XmStringCharSet charset = (XmStringCharSet)XmSTRING_DEFAULT_CHARSET; /********************** main **********************/ void main(int argc,char ** argv) { Widget toplevel; Widget main_window; XtAppContext app_context; toplevel = XtVaAppInitialize(&app_context,"XMdemos",NULL,0, &argc,argv,NULL,XmNallowShellResize,True,NULL); main_window = MyCreateMain(toplevel); XtRealizeWidget(toplevel); XtAppMainLoop(app_context); } /********************* MyCreateMain *************************/ Widget MyCreateMain(Widget parent) { Widget main_window; Widget menu_bar; Widget menu_pane; Widget cascade; Widget frame; Widget form; Widget button; Widget hsb,vsb; Arg args[MAX_ARGS]; register int n; DIR *dirp; #if defined(SYS_DIR)||defined(NDIR) struct direct *item; #else struct dirent *item; #endif char filename[80]; int len; int i,j,k; XmString label_string; XmString stringx[2]; /***************** Init Data *************/ InitData(); printf("piont3.0\n"); /***************** Create MainWindow *************/ n = 0; main_window = XmCreateMainWindow(parent,"main1",args,n); XtManageChild(main_window); /***************** Create MenuBar ***************/ n = 0; menu_bar = XmCreateMenuBar(main_window,"menu_bar",args,n); XtManageChild(menu_bar); XmAddTabGroup(menu_bar); /***************** Create "exit" menu ************/ n = 0; menu_pane = XmCreatePulldownMenu(menu_bar,"menu_pane",args,n); n = 0; button = XmCreatePushButton(menu_pane,"Quit",args,n); XtManageChild(button); XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))QuitCB,(XtPointer)NULL); n = 0; button = XmCreatePushButton(menu_pane,"Display",args,n); XtManageChild(button); XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))MenuCommandCB,(XtPointer)MENU_DISPLAY_POSITION); n = 0; button = XmCreatePushButton(menu_pane,"Next",args,n); XtManageChild(button); XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))MenuCommandCB,(XtPointer)MENU_NEXT_POSITION); printf("piont3.2\n"); n = 0; XtSetArg(args[n],XmNsubMenuId,menu_pane);n++; cascade = XmCreateCascadeButton(menu_bar,"Exit",args,n); XtManageChild(cascade); /***************** Create "help" menu ************/ n = 0; //cascade = XmCreateCascadeButton(menu_bar,"help",args,n); cascade = XmCreateCascadeButtonGadget(menu_bar,"help",args,n); XtManageChild(cascade); XtAddCallback(cascade,XmNactivateCallback,(void (*)(Widget,void *, void *))HelpCB,(XtPointer)1); n = 0; XtSetArg(args[n],XmNmenuHelpWidget,cascade);n++; XtSetValues(menu_bar,args,n); /***************** Create Frame window ********/ n = 0; XtSetArg(args[n],XmNmarginWidth,2);n++; XtSetArg(args[n],XmNmarginHeight,2);n++; XtSetArg(args[n],XmNshadowThickness,1);n++; XtSetArg(args[n],XmNshadowType,XmSHADOW_OUT);n++; frame = XmCreateFrame(main_window,"frame",args,n); XtManageChild(frame); /***************** Create command window ********/ n = 0; form = XmCreateForm(frame,"form",args,n); XtManageChild(form); n = 0; XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM);n++; XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM);n++; XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM);n++; command_window = XmCreateTextField(form,"textfield",args,n); XtManageChild(command_window); /***************** Create Scrolled list ***************/ n = 0; XtSetArg(args[n],XmNtopAttachment,XmATTACH_WIDGET);n++; XtSetArg(args[n],XmNtopWidget,command_window);n++; XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM);n++; XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM);n++; XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM);n++; XtSetArg(args[n],XmNscrollBarDisplayPolicy,XmAS_NEEDED);n++; XtSetArg(args[n],XmNscrollingPolicy,XmAUTOMATIC);n++; XtSetArg(args[n],XmNvisibleItemCount,30);n++; XtSetArg(args[n],XmNlistMarginWidth,5);n++; XtSetArg(args[n],XmNwidth,400);n++; XtSetArg(args[n],XmNlistSizePolicy,XmCONSTANT);n++; slist = XmCreateScrolledList(form,"slist",args,n); XtManageChild(slist); /**************** Set MainWindow areas and add tab groups ******* XmMainWindowSetAreas(main_window,menu_bar,NULL,NULL,NULL,frame); n = 0; XtSetArg(args[n],XmNhorizontalScrollBar,&hsb);n++; XtSetArg(args[n],XmNverticalScrollBar,&vsb);n++; XtGetValues(swindow,args,n); XmAddTabGroup(slist); printf("hsb = %x, vsb = %x",hsb,vsb); if(hsb) XmAddTabGroup(hsb); if(vsb) XmAddTabGroup(vsb); */ XmAddTabGroup(slist); XmAddTabGroup(command_window); //system("ls /home/wxk/x "); /**************** Create items in the slist **********/ for (i=0;iname,charset); XmListAddItem(slist,label_string,0); //if (!strcmp(filename,"core")) stringx[0] = label_string; XmStringFree(label_string); } n = 0; //XtSetArg(args[n],XmNselectedItemCount,1);n++; //XtSetArg(args[n],XmNselectedItems,stringx);n++; //XtSetArg(args[n],XmNtopItemPosition,14);n++; XtSetValues(slist,args,n); XtAddCallback(slist,XmNbrowseSelectionCallback,(void (*)(Widget,void *, void *))ListSelectCB,(XtPointer)NULL); XtAddCallback(slist,XmNdefaultActionCallback,(void (*)(Widget,void *, void *))ActiveCB,(XtPointer)NULL); XtAddCallback(command_window,XmNvalueChangedCallback,(void (*)(Widget,void *, void *))CommandWindowInputCB,(XtPointer)NULL); XtAddCallback(command_window,XmNactivateCallback,(void (*)(Widget,void *, void *))ActiveCB,(XtPointer)NULL); printf("piont3.10\n"); return(main_window); } /********************* SelectFontCB ***********************/ Widget SelectedFontSample(Widget widget) { Widget message_box; Widget button; Arg args[MAX_ARGS]; register int n; int i; XtPointer * buffer; char *name = NULL; XFontStruct * font = NULL; XmFontList fontlist = NULL; static char message[BUFSIZ]; XmString name_string = NULL; XmString message_string = NULL; XmString button_string = NULL; /******************* get font name *********************/ printf("piont SelectedFontSample\n"); XtVaGetValues(widget,XmNlabelString,&name_string,NULL); XmStringGetLtoR(name_string,charset,&name); /* for(i=0;i<10;i++) { if(name) font = XLoadQueryFont(XtDisplay(XtParent(widget)),name); if(font == NULL) sprintf(message,"Unable to load font:%s.",name); else { fontlist = XmFontListCreate(font,charset); sprintf(message,"\n This is font %s.\n The quick brown fox jumps over the lazy dog.",name); } printf("font=%x, fontlist=%x\n",font,fontlist); XmFontListFree(fontlist); if(font) XFreeFont(XtDisplay(XtParent(widget)),font); } */ if(name) font = XLoadQueryFont(XtDisplay(XtParent(widget)),name); if(font == NULL) sprintf(message,"Unable to load font:%s.",name); else { fontlist = XmFontListCreate(font,charset); sprintf(message,"\n This is font %s.\n The quick brown fox jumps over the lazy dog.",name); } printf("font=%x, fontlist=%x\n",font,fontlist); buffer = (XtPointer*)XtMalloc(sizeof(XtPointer)*2); printf("buffer=%x, size=%d\n",buffer,sizeof(XtPointer)*2); buffer[0] = (XtPointer)fontlist; buffer[1] = (XtPointer)font; printf("piont SelectedFontSample, name=%x, name_string=%x, font=%x\n",name,name_string,font); message_string = XmStringCreateLtoR(message,charset); for(i=0;i<0;i++) { button_string = XmStringCreateLtoR("Close",charset); printf("button_string=%x\n",button_string); XmStringFree(button_string); } button_string = XmStringCreateLtoR("Close",charset); n = 0; if (fontlist) { XtSetArg(args[n],XmNlabelFontList,fontlist);n++; } XtSetArg(args[n],XmNdialogTitle,name_string);n++; XtSetArg(args[n],XmNokLabelString,button_string);n++; XtSetArg(args[n],XmNmessageString,message_string);n++; for(i=0;i<0;i++) { message_box = XmCreateMessageDialog(XtParent(XtParent(widget)),"fontbox",args,n); XtDestroyWidget(message_box); } message_box = XmCreateMessageDialog(XtParent(XtParent(widget)),"fontbox",args,n); XtAddCallback(message_box,XmNokCallback,(void (*)(Widget,void *, void *))CloseCB,(XtPointer)buffer); XtAddCallback(message_box,XmNhelpCallback,(void (*)(Widget,void *, void *))HelpCB,(XtPointer)2); button = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON); //if(name_string) XmStringFree(name_string); //XtVaGetValues(button,XmNlabelString,&name_string,NULL); //if(name_string) XmStringFree(name_string); XtUnmanageChild(button); //XtDestroyWidget(button); //if(fontlist) XmFontListFree(fontlist); if(name) XtFree((char*)name); //if(name_string) XtFree((char*)name_string); //if(message_string) XtFree((char*)message_string); //if(button_string) XtFree((char*)button_string); if(button_string) XmStringFree(button_string); if(message_string) XmStringFree(message_string); printf("button_string=%x, message_string=%x, name_string=%x\n",button_string,message_string,name_string); return (message_box); } Widget MyHelpDialog(Widget parent,int flag) { static int first_time = 1; static Widget message_box; Arg args[MAX_ARGS]; register int n; static char message[BUFSIZ]; XmString title_string = NULL; static XmString message_string1 = NULL; static XmString message_string2 = NULL; XmString button_string = NULL; if (first_time) { Widget wtmp; n = 0; message_box = XmCreateMessageDialog(XtParent(XtParent(parent)),"helpbox",args,n); button_string = XmStringCreateLtoR("Close",charset); title_string = XmStringCreateLtoR("myfonts help",charset); message_string1 = XmStringCreateLtoR("\nPush one button to get the sample " "\ntext display in the font.\n(Some font may not be opened.)",charset); message_string2 = XmStringCreateLtoR("\n The help text for this specific font.\n",charset); XtVaSetValues(message_box,XmNdialogTitle,title_string,XmNokLabelString,button_string,NULL); wtmp = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON); XtUnmanageChild(wtmp); wtmp = XmMessageBoxGetChild(message_box,XmDIALOG_HELP_BUTTON); XtUnmanageChild(wtmp); first_time = 0; } if (flag == 1) XtVaSetValues(message_box,XmNmessageString,message_string1,NULL); else XtVaSetValues(message_box,XmNmessageString,message_string2,NULL); return (message_box); } void FontSelectedCB(Widget w,caddr_t client_data,caddr_t call_data) { Widget message_box; //putchar(007);fflush(stdout); message_box = SelectedFontSample(w); XtManageChild(message_box); } void CloseCB(Widget w,caddr_t client_data,caddr_t call_data) { XmString message_string = NULL; XmString button_string = NULL; XmString name_string = NULL; Widget button; XtPointer * buffer; Widget message_box = XtParent(w); buffer = (XtPointer*)client_data; printf("buffer=%x, call_data=%x\n",buffer,call_data); //putchar(007);fflush(stdout); //XtVaGetValues(w,XmNokLabelString,&button_string,XmNmessageString,&message_string,XmNdialogTitle,&name_string,NULL); //printf("freeing button_string=%x, message_string=%x\n",button_string,message_string); XtUnmanageChild(message_box); XtDestroyWidget(message_box); if(buffer[0]) XmFontListFree((XmFontList)buffer[0]); //printf("font=%x, fontlist=%x\n",buffer[1],buffer[0]); if(buffer[1]) XFreeFont(XtDisplay(XtParent(w)),(XFontStruct *)buffer[1]); XtFree((char*)buffer); /* if(button_string) XmStringFree(button_string); if(button_string) XmStringFree(button_string); if(message_string) XmStringFree(message_string); if(message_string) XmStringFree(message_string); */ } void HelpCB(Widget w,int tag,caddr_t call_data) { Widget message_box; int i = tag; printf("tag=%d\n",tag); //putchar(007);fflush(stdout); message_box = MyHelpDialog(w,i); XtManageChild(message_box); } void QuitCB(Widget w,caddr_t client_data,caddr_t call_data) { //putchar(007);fflush(stdout); exit(0); } void MenuCommandCB(Widget w,caddr_t client_data,caddr_t call_data) { Arg args[MAX_ARGS]; int command; int n; int *position; int buffer[4]; command = (int)client_data; switch(command) { case MENU_DISPLAY_POSITION: n = 0; XtSetArg(args[n],XmNselectedPositions,&position);n++; XtGetValues(slist,args,n); if(position) printf("MenuCommandCB: position[0] = %d\n",*position); else printf("MenuCommandCB: position = NULL\n"); break; case MENU_NEXT_POSITION: n = 0; XtSetArg(args[n],XmNselectedPositions,&position);n++; XtGetValues(slist,args,n); if(position) { buffer[0] = *position + 1; XmListDeselectAllItems(slist); n = 0; XtSetArg(args[n],XmNselectedPositions,buffer);n++; XtSetArg(args[n],XmNselectedPositionCount,1);n++; XtSetValues(slist,args,n); } else { buffer[0] = 10; n = 0; XtSetArg(args[n],XmNselectedPositions,buffer);n++; XtSetArg(args[n],XmNselectedPositionCount,1);n++; XtSetValues(slist,args,n); } break; default: printf("undefined command\n"); } } void ListSelectCB(Widget w,caddr_t client_data,XmListCallbackStruct * callback_data) { Arg args[MAX_ARGS]; int n; int *position; n = 0; XtSetArg(args[n],XmNselectedPositions,&position);n++; XtGetValues(slist,args,n); //printf("ListSelectCB: position = %d\n",*position); //n = 0; //XtSetArg(args[n],XmNtopItemPosition,(*position-1)?(*position-1):1);n++; //XtSetValues(slist,args,n); call_back_signal = 1; XmTextSetString(command_window,item_list[*position-1]->name); } void ActiveCB(Widget w,caddr_t client_data,caddr_t call_data) { Arg args[MAX_ARGS]; int n; int *position; n = 0; XtSetArg(args[n],XmNselectedPositions,&position);n++; XtGetValues(slist,args,n); if(!position) return; //printf("active = %d, name = %s\n",position[0]-1,item_list[position[0]-1]->name); active_man_page(item_list[position[0]-1]); } void CommandWindowInputCB(Widget w,caddr_t client_data,caddr_t call_data) { Arg args[MAX_ARGS]; int n; int count; char * name; int position; int *positions; if (call_back_signal) { call_back_signal = 0; return; } name = XmTextGetString(command_window); position = ItemMatch(name); position ++; //printf("match position = %d\n",position); XtFree(name); XmListDeselectAllItems(slist); n = 0; XtSetArg(args[n],XmNselectedPositionCount,1);n++; XtSetArg(args[n],XmNselectedPositions,&position);n++; XtSetArg(args[n],XmNtopItemPosition,(position-1)?(position-1):1);n++; XtSetValues(slist,args,n); } /************************* ManPath ************************/ ManPath::ManPath(char* path_name) { int i; int len; next = NULL; alias = NULL; len = strlen(path_name); man_path = (char*)malloc(len+1); strncpy(man_path,path_name,len); man_path[len] = '\0'; for (i=0;i<11;i++) sub_dir[i] = new SubDir(this); LoadManPath(path_name); } ManPath::~ManPath() { int i; for (i = 0;i<11;i++) delete(sub_dir[i]); free(man_path); } ManPath::GetSize(char c) { int count; int i; int type = subdir_translate_c_to_n(c)+1; if (type <= 11 && type >= 1) return sub_dir[type-1]->GetSize(); for (i = count = 0;i<11;i++) count += sub_dir[i]->GetSize(); return count; } ManPath::GetItems(char c, ManItem * buffer[]) { int count; int i; int type = subdir_translate_c_to_n(c)+1; if (type <= 11 && type >= 1) return sub_dir[type-1]->GetItems(buffer); for (i = count = 0;i<11;i++) count += sub_dir[i]->GetItems(buffer+count); return count; } struct stat state; ManPath::LoadManPath(char * path_name) { DIR *dirp; #if defined(SYS_DIR)||defined(NDIR) struct direct *item; #else struct dirent *item; #endif int len; int val; char name[180]; man_path = (char*)realloc(man_path,strlen(path_name)+1); strcpy(man_path,path_name); dirp = opendir(path_name); if (!dirp) { fprintf(stderr,"Can not open man path %s\n",path_name); } for (item = readdir(dirp);item != NULL;item = readdir(dirp)) { if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0))) continue; attach(name,path_name,item->d_name); val = stat (name, &state); if (val < 0) fprintf(stderr,"error number %d, in get state %s",errno,name); else if (S_ISDIR(state.st_mode)) LoadManPath(name); else { len = (strlen(item -> d_name)); if(item -> d_name[len-2] == '.') { val = subdir_translate_c_to_n(item->d_name[len-1]); strncpy(name,item->d_name,len-2); name[len-2] = '('; name[len-1] = item->d_name[len-1]; name[len] = ')'; name[len+1] = '\0'; sub_dir[val]->AddItem(name); } else if(item -> d_name[len-3] == '.') { val = subdir_translate_c_to_n(item->d_name[len-2]); strncpy(name,item->d_name,len-3); name[len-3] = '('; name[len-2] = item->d_name[len-2]; name[len-1] = item->d_name[len-1]; name[len] = ')'; name[len+1] = '\0'; sub_dir[val]->AddItem(name); } } } } /************************* SubDir ************************/ SubDir::SubDir(ManPath* path) { man_path = path; buffer_length = 64; count = 0; item_list = (ManItem**)malloc(buffer_length*sizeof(ManItem*)); } SubDir::~SubDir() { int i; for (i=0;i= buffer_length) item_list = (ManItem**)realloc(item_list,(buffer_length*=2)*sizeof(*item_list)); item_list[count++] = new ManItem(this,file_name); } inline SubDir::GetSize() { return count; } SubDir::GetItems(ManItem *buffer[]) { memcpy(buffer,item_list,count*sizeof(ManItem*)); return count; } /************************* ManItem ************************/ inline ManItem::ManItem(SubDir * sub,char *name) { int len; len = strlen(name); this->name = (char*)malloc(len+1); strncpy(this->name,name,len); this->name[len] = '\0'; } inline ManItem::~ManItem() { free(name); } /************************* init global data ************************/ void InitData() { int i; man_paths = NULL; item_list = NULL; item_list_length = 0; item_list_count = 0; man_paths = new ManPath("/usr/X11/man/"); printf("GetSize = %d\n",man_paths->GetSize('a')); item_list_length = item_list_count = man_paths->GetSize('a'); printf("GetSize = %d\n",item_list_count); item_list = (ManItem**)malloc(item_list_count*sizeof(ManItem*)); man_paths->GetItems('a',item_list); qsort(item_list,item_list_count,sizeof(ManItem*),&ManItemComp); //for(i=0;iname); } /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */ static void attach (char *dest, const char *dirname, const char *name) { const char *dirnamep = dirname; /* Copy dirname if it is not ".". */ if (dirname[0] != '.' || dirname[1] != 0) { while (*dirnamep) *dest++ = *dirnamep++; /* Add '/' if `dirname' doesn't already end with it. */ if (dirnamep > dirname && dirnamep[-1] != '/') *dest++ = '/'; } while (*name) *dest++ = *name++; *dest = 0; } int subdir_translate_c_to_n(char c) { if(c<='8' && c>='1') return (c-'1'); else if(c == 'n') return 8; else if(c == 'l') return 9; else if(c == 'a') return -1; else return 10; } int ManItemComp(ManItem ** a,ManItem ** b) { return (strcmp((*a)->name,(*b)->name)); } int ItemMatch(char * name) { int i; for (i=0;iname)>0 ;i++); return (i >= item_list_count)? i-1:i; } static void active_man_page(ManItem * item) { int i; int len,len2; char buffer[180]; len = strlen(item->name); if (item->name[len-3] == '(') len -= 3; else len -= 4; strcpy(buffer,"nxterm -T '"); strcat(buffer,item->name); strcat(buffer,"' -n KMan -e man "); len2 = strlen(buffer); strncat(buffer,item->name,len); buffer[len+len2] = '\0'; if(!fork()) { //printf(buffer); system(buffer); exit(0); } return; }