gman-0.9.3/0040755000311700000120000000000007472445074011152 5ustar wxkwheelgman-0.9.3/config.h0100644000311700000120000000047307472365646012577 0ustar wxkwheel/* config.h. Generated automatically by configure. */ /* config.h.in. Generated automatically from configure.in by autoheader. */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Name of package */ #define PACKAGE "project1" /* Version number of package */ #define VERSION "0.1" gman-0.9.3/context.c0100644000311700000120000001263107472365646013010 0ustar wxkwheel/****************** context.c ******************/ /****************** 1999.6.17 ******************/ #include #include #include "context.h" #include "util.h" AppContext::AppContext() { names = new List(); types = new List(); values = new List(); name_default = new List(); type_default = new List(); value_default = new List(); set_default_value("h_size","int",(void *)300); set_default_value("v_size","int",(void *)200); } AppContext::~AppContext() { delete names; delete types; delete values; delete name_default; delete type_default; delete value_default; } int AppContext::search_name(List * list,char * name) { int i,j; j = list->get_size(); for (i = 0;i < j;i++) if (!strcmp((char*)(list->get_item(i)),name)) break; return (iget_item(i),type)) { if((i = search_name(names,_name)) != -1) values->reset_item(i,data); else{ values->add_item(data); types->add_item(type); names->add_item(_name); } } else { fprintf(stderr,"Warning: class AppContext: data type mismatch, " " variable \"%s\" is a \"%s\" instead of \"%s\"\n", name_default->get_item(i),type_default->get_item(i),type); return 1; } } else { if((i = search_name(names,_name)) != -1) values->reset_item(i,data); else{ values->add_item(data); types->add_item(type); names->add_item(_name); } } return 0; } void * AppContext::get_value(char * _name) { int i; if((i = search_name(names,_name)) != -1) return values->get_item(i); else if ((i = search_name(name_default,_name)) != -1) return value_default->get_item(i); return 0; } char * AppContext::get_value_type(char * _name) { int i; if((i = search_name(names,_name)) != -1) return (char*)types->get_item(i); else if ((i = search_name(name_default,_name)) != -1) return (char*)type_default->get_item(i); return NULL; } void AppContext::set_default_value(char * _name, char * type, void * data) { int i; if((i = search_name(name_default,_name)) != -1) { value_default->reset_item(i,data); type_default->reset_item(i,type); } else{ name_default->add_item(_name); type_default->add_item(type); value_default->add_item(data); } } void AppContext::restore_default(char * _name) { int i; if((i = search_name(names,_name)) != -1) { values->delete_item(i); types->delete_item(i); names->delete_item(i); } } void AppContext::restore_all() { names->delete_all(); types->delete_all(); values->delete_all(); } void AppContext::display_values() { int i,j,k; printf("values:\n"); j = names->get_size(); for(i = 0; iget_item(i),"char*")) printf("\"%s\" = \"%s\"\n",names->get_item(i),values->get_item(i)); else if(!strcmp((char*)types->get_item(i),"int")) printf("\"%s\" = %d\n",names->get_item(i),values->get_item(i)); else printf("\"%s\" = 0x%x\n",names->get_item(i),values->get_item(i)); printf("default values:\n"); j = name_default->get_size(); for(i = 0; iget_item(i),"char*")) printf("\"%s\" = \"%s\"\n",name_default->get_item(i),value_default->get_item(i)); else if(!strcmp((char*)type_default->get_item(i),"int")) printf("\"%s\" = %d\n",name_default->get_item(i),value_default->get_item(i)); else printf("\"%s\" = 0x%x\n",name_default->get_item(i),value_default->get_item(i)); } #define BUFFER_LENGTH 200 #define BEGIN 1 #define NAME 2 #define NAME_ESCAPE 4 #define VALUE 3 static int is_blank(char c) { return c==' ' || c==9;} static int is_end(char c) { return c=='\n' || c == 0;} static int is_number(char c) {return c<='9' && c>='0';} static void * my_parser(char *a, char ** type) { char * b; int n; for(b = a; is_number(*b) && !is_blank(*b) && !is_end(*b);b++); if(!(is_blank(*b)||is_end(*b))) { for(;!is_blank(*b) && !is_end(*b);b++); *b = '\0'; *type = "char*"; return (void*)my_strdup(a); } else { *type = "int"; sscanf(a,"%d",&n); return (void*) n; } } void AppContext::load(FILE * fd) { int i,j,k,state; long pos; char *a,*b,*c,*name,*type; void * value; char buffer[BUFFER_LENGTH]; a = buffer; pos = 0L; for(k = 1;k;){ fseek(fd,pos,SEEK_SET); i = fread(buffer,1,BUFFER_LENGTH-1,fd); if (i == 0) break; buffer[i] = '\0'; //printf(buffer); b = strchr(buffer,(int)'\n'); if (b) { pos += b - buffer +1; *b = '\0'; } else k = 0; for(a = buffer;is_blank(*a) && !is_end(*a);a++); if (*a == '#' || is_end(*a)) continue; for(b = a;!is_blank(*b) && !is_end(*b) && *b != '=';b++); if(is_end(*b)) continue; c = strchr(b,(int)'='); if(!c) continue; c++; for(;is_blank(*c) && !is_end(*c);c++); if(is_end(*c)) continue; *b = 0; // printf("name = %s, value = %s",a,c); name = my_strdup(a); value = my_parser(c,&type); set_value(name,type,value); } } void AppContext::save(FILE * fp, char * header) { int i,j,k; char * type; if(header != NULL) fprintf(fp,"#%s\n\n",header); j = names->get_size(); for (i = 0;iget_item(i); if (!strcmp(type,"char*")) fprintf(fp,"%s = %s\n",names->get_item(i),values->get_item(i)); else if (!strcmp(type,"int")) fprintf(fp,"%s = %d\n",names->get_item(i),values->get_item(i)); else fprintf(stderr,"class AppContext: save: type \"%s\" does not be supported yet.\n",type); } } #undef BUFFER_LENGTH gman-0.9.3/context.h0100644000311700000120000000163607472365646013020 0ustar wxkwheel/******************** context.h ********************/ #ifndef _CONTEXT_H #define _CONTEXT_H #include #include "list.h" class AppContext { public: AppContext(); ~AppContext(); void * get_value(char * name); char * get_value_type(char * name); int set_value(char * name, char * type, void * buffer); void set_default_value(char *name, char * type, void * buffer); /* AppContext::set_value() and set_default_value() only implement simpliest data management function. If the name or type is in a temp buffer, it is caller's duty to do strdup() before call the set_value() or set_default_value() */ void restore_default(char * name); void restore_all(); void load(FILE *); void save(FILE *, char *); void display_values(); private: int search_name(List*, char *); List * names; List * types; List * values; List * name_default; List * type_default; List * value_default; }; #endif gman-0.9.3/gman.c0100644000311700000120000000671307472365646012252 0ustar wxkwheel/********************* gman.c ********************************/ /* gman * Copyright (C) 1999 Xinkai Wang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include "menu.h" #include "context.h" #include "gman.h" #include "task.h" #include "taskfunc.h" #include "mandata.h" #include void init_context(); pthread_mutex_t gtk_lock; pthread_mutex_t context_lock; pthread_mutex_t loading_man_path_lock; AppContext * context; int debuging; /********************** main **********************/ TaskGroup * task_group; int main(int argc, char *argv[]) { GtkWidget *window; pthread_t th_init_data; pthread_mutex_init(>k_lock,NULL); pthread_mutex_init(&context_lock,NULL); pthread_mutex_init(&loading_man_path_lock,NULL); init_context(); debuging = (int)context->get_value("debuging"); pthread_mutex_lock(>k_lock); gtk_init (&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); task_group = task_group_new(); init_thread(task_group); init_main_window(window); gtk_widget_show(window); pthread_mutex_unlock(>k_lock); //pthread_create(&th_init_data, NULL, (void * (*)(void*))init_man_data, 0); //gtk_main(); while(1){ pthread_mutex_lock(>k_lock); while(gtk_events_pending()) { gtk_main_iteration(); } pthread_mutex_unlock(>k_lock); usleep(10000); } return(0); } /******************* init_context() *****************/ void init_context() { FILE * fd; char buffer[256]; context = new AppContext(); // context->set_default_value("v_size",(void*)400); context->set_default_value("debuging","int",(void*)0); context->set_default_value("man_paths","char*",(void*)"/usr/man:/usr/local/man:/usr/X11R6/man"); context->set_default_value("display_section_policy","int",(void*)0); context->set_default_value("display_section","int",(void*)3); context->set_default_value("searching_mode","int",(void*)0); context->set_default_value("show_status_bar","int",(void*)0); context->set_default_value("show_warning","int",(void*)0); context->set_default_value("show_mode","int",(void*)0); // 0 = xterm, 1 = ghostview context->set_default_value("xterm_command","char*",(void*)"xterm"); // rxvt, Eterm also works context->set_default_value("gv_command","char*",(void*)"gv"); context->set_default_value("browser_command","char*",(void*)"netscape"); // kfm also works context->set_default_value("cgi_host","char*",(void*)"localhost"); context->set_default_value("cgi_location","char*",(void*)"/cgi-bin/gman/gman.pl"); context->set_default_value("print_command","char*",(void*)"lpr"); // not in use attach(buffer,getenv("HOME"),".gman"); if((fd = fopen(buffer,"r"))) { context->load(fd); fclose(fd); } if(context->get_value("debuging")) context->display_values(); //context->save(stdout,"this is just a test"); } gman-0.9.3/gman.h0100644000311700000120000000046007472365646012250 0ustar wxkwheel/******************** context.h ********************/ #ifndef _GMAN_H #define _GMAN_H #include "context.h" #include extern pthread_mutex_t gtk_lock; extern pthread_mutex_t context_lock; extern pthread_mutex_t loading_man_path_lock; extern AppContext * context; extern int debuging; #endif gman-0.9.3/gripedefs.h0100644000311700000120000000025407472365646013277 0ustar wxkwheel#define CANNOT_FORK 1 #define WAIT_FAILED 2 #define GOT_WRONG_PID 3 #define CHILD_TERMINATED_ABNORMALLY 4 #define NO_EXEC 5 #define SYSTEM_FAILED 6 #define OUT_OF_MEMORY 7 gman-0.9.3/kman.h0100644000311700000120000000202707472365646012255 0ustar wxkwheel/********************** modified from t2.c *******************/ /********************* kman.h ********************************/ #include "list.h" #ifndef _KMAN_H #define _KMAN_H #define MAX_MAN_SECTION 15 #define BUFFER_SIZE 200 class ManPath; class ManItem; class ManPath { private: char * path_name; List * section[MAX_MAN_SECTION]; //1:2:3:4:5:6:7:8:9:tcl:n:l:p:o private: int LoadManSubPath(char *); public: ManPath(char * path_name); ~ManPath(); int LoadManPath(char *); const char * GetPath(); int GetSize(int section_ID); int GetItems(int section_ID, ManItem **buffer); }; class ManItem { public: ManItem(ManPath *, char * file_name); ~ManItem(); char * get_display_name(char * buffer); char * get_section_name(char * buffer); int get_section_ID(); void * get_man_path(); void active_man_page(); private: ManPath * man_path; char * file_name; char * display_name; char * section_name; int section_ID; }; //int ItemMatch(char * name); int man_item_compare(ManItem **,ManItem **); #endif /* _KMAN_H */ gman-0.9.3/list.c0100644000311700000120000000702607472365646012301 0ustar wxkwheel/********************* list.c **********************/ /********************* 1999.6.13 *******************/ #include "list.h" #include #include #include #include #include #define LIST_INIT_SIZE 15 List::List() { items = NULL; buffer_length = 0; count = 0; }; List::~List() { if(items) free(items); }; void List::add_item(void * item) { if(!items) { items = (void **)malloc((size_t)sizeof(void*)*LIST_INIT_SIZE); if(!items) { perror("class List: can not malloc mem when init:"); exit(1); } buffer_length = LIST_INIT_SIZE; } else if(buffer_length == count){ items = (void **)realloc((void*)items,sizeof(void *)*(buffer_length+=buffer_length)); if(!items){ perror("class List: mem not enought when realloc:"); exit(1); } } items[count++] = item; } void * List::get_item(int handle) { if(handle >= count || handle < 0) return NULL; return items[handle]; } int List::reset_item(int handle, void * data) { if(handle >= count || handle < 0) return 1; items[handle] = data; return 0; } int List::search_item(void * item) { int i; for (i = 0;i < count && items[i] != item;i++); return (i == count)? -1:i; } int List::delete_item(int handle) { g_return_val_if_fail(handle < count && handle >= 0, 1); if(handle != count-1) memmove(items+handle, items+(handle+1), (count-handle-1)*sizeof(void*)); count--; return 0; } void List::insert_item(int handle, void * item) { int i; if(!items) { items = (void **)malloc(sizeof(void*)*LIST_INIT_SIZE); if(!items) { perror("class List: can not malloc mem when init:"); exit(1); } buffer_length = LIST_INIT_SIZE; } else if(buffer_length == count){ items = (void **)realloc((void*)items,sizeof(void *)*(buffer_length+=buffer_length)); if(!items){ perror("class List: mem not enought when realloc:"); exit(1); } } if(handle >= count) items[count++] = item; else { handle = handle <0? 0:handle; for(i = count++;i>handle;i--) items[i] = items[i-1]; items[handle] = item; } } void List::delete_all() { count = 0; } int List::get_items(void * buffer) { memcpy((void *)buffer,(void *)items,count*sizeof(void*)); return count; } int List::get_size() { return count; } int List::meet_end(int handle) { return (handle >= count)? 1:0; } /********************* class Dictionary ***************/ Dictionary::Dictionary() { names = new List; values = new List; } Dictionary::~Dictionary() { delete(names); delete(values); } void Dictionary::add_item(char * name,void * value) { int i; if((i = search_item(name)) != -1) { values->reset_item(i,value); } else { names->add_item(name); values->add_item(value); } } int Dictionary::search_item(char * name) { int i,j; j = names->get_size(); for(i = 0;iget_item(i));i++); return (i==j)? -1:i; } int Dictionary::have_item(char * name) { return search_item(name) != -1; } void * Dictionary::get_value(char * name) { int i; i = names->search_item(name); return (i==-1)? NULL:values->get_item(i); } int Dictionary::get_size() { return names->get_size(); } void * Dictionary::get_value(int i) { return values->get_item(i); } char * Dictionary::get_name(int i) { return (char*)names->get_item(i); } void Dictionary::set_value(int i, void * value) { values->reset_item(i,value); } void Dictionary::delete_item(int i) { names->delete_item(i); values->delete_item(i); } void Dictionary::display_items() { int i,j; j = names->get_size(); for(i = 0;iget_item(i)); } gman-0.9.3/list.h0100644000311700000120000000166007472365646012304 0ustar wxkwheel/******************** list.h *****************/ /******************** 1999.6.13 *************/ #ifndef _LIST_H #define _LIST_H class List { private: void ** items; int buffer_length; int count; public: List(); ~List(); void add_item(void * item); void * get_item(int handle); int reset_item(int handle,void * item); int search_item(void * item); int delete_item(int handle); void insert_item(int handle, void * item); void delete_all(); int get_size(); int get_items(void * buffer); int meet_end(int handle); }; class Dictionary { private: List * names; List * values; public: Dictionary(); ~Dictionary(); void add_item(char * name,void * value); int have_item(char * name); int search_item(char * name); void * get_value(char* name); int get_size(); void * get_value(int i); char * get_name(int i); void set_value(int i,void * value); void delete_item(int i); void display_items(); }; #endif gman-0.9.3/mandata.c0100644000311700000120000002364707472365646012742 0ustar wxkwheel/********************** modified from t2.c *******************/ /********************* kman.c ********************************/ #include #include #include #ifdef SYS_DIR #include #else #ifdef NDIR #include #else #include #endif #endif #include #include #include #include "mandata.h" #include "mandatadef.h" #include "util.h" #include "context.h" #include "gman.h" #include #include void attach (char *dest, const char *dirname, const char *name); static int section_translate_c_to_n(const char* c); static int ManItemComp(ManItem ** a,ManItem ** b); static int is_zip_suffix(char* c); char buffer1[BUFFER_SIZE]; char buffer2[BUFFER_SIZE]; /************************* ManPath ************************/ ManPath::ManPath(char* _path_name) { int i; int len; active = 1; path_name = my_strdup(_path_name); for (i=0;iget_size(); for(j = 0;jget_item(j))); delete(section[i]); } if(path_name) free(path_name); } int ManPath::GetSize(int section_ID) { int count; int i; for (count = i = 0;iget_size(); return count; } int ManPath::GetItems(int section_ID, ManItem * buffer[]) { int count; int i; for (count = i = 0;iget_items((void*)(buffer + count)); return count; } const char * ManPath::GetPath() {return (const char*) path_name;} struct stat state; int ManPath::LoadManPath(char * path_name) { DIR *dirp; #if defined(SYS_DIR)||defined(NDIR) struct direct *item; #else struct dirent *item; #endif ManItem * man_item; int val,i; // printf("LoadManPath: %s\n",path_name); dirp = opendir(path_name); if (!dirp) { fprintf(stderr,"Can not open man path %s\n",path_name); return 1; } 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(buffer1,path_name,item->d_name); //printf("LoadManPath: %s\n",name); val = stat (buffer1, &state); if (val < 0) fprintf(stderr,"error number %d, in get state %s",errno,buffer1); else if (S_ISDIR(state.st_mode) && !strncmp(item->d_name,"man",3)) LoadManSubPath(item->d_name); else { man_item = new ManItem(this,item -> d_name); val = man_item->get_section_ID(); if(!val) delete(man_item); else{ for(i = 0;!(1<add_item(man_item); } //printf("%d\n",n); } } closedir(dirp); return 0; } int ManPath::LoadManSubPath(char * sub_name) { DIR *dirp; #if defined(SYS_DIR)||defined(NDIR) struct direct *item; #else struct dirent *item; #endif int val,i; ManItem * man_item; attach(buffer2,path_name,sub_name); //printf("LoadManSubPath: %s\n",buffer2); dirp = opendir(buffer2); if (!dirp) { fprintf(stderr,"Can not open man path %s\n",buffer2); } 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(buffer1,buffer2,item->d_name); //printf("LoadManSubPath: %s\n",full_name); val = stat (buffer1, &state); if (val < 0) fprintf(stderr,"error number %d, in get state %s\n",errno,buffer1); else if (S_ISDIR(state.st_mode)) continue; else { attach(buffer1,sub_name,item->d_name); man_item = new ManItem(this,buffer1); val = man_item->get_section_ID(); if(!val) delete(man_item); else{ for(i = 0;!(1<add_item(man_item); } } } closedir(dirp); } ManItem * ManPath::search_man_item(char * name, char * sect) { int i,j,k; int len; ManItem * a; char buffer[100]; len = strlen(name); if(section) { j = section_translate_c_to_n(sect); //printf("point0.1\n"); if(!j) return NULL; for(i = 0;!(1<get_size(); //printf("point0.25, k = %d\n",k); for(j = 0;jget_item(j)); if(!strcmp(name,a->get_display_name(buffer))) return a; } a = NULL; } return NULL; } /************************* ManItem ************************/ inline ManItem::ManItem(ManPath* _man_path, char* _file_name) { file_name = my_strdup(_file_name); man_path = _man_path; display_name = strrchr(file_name,'/'); display_name = display_name? display_name + sizeof('/'):file_name; section_name = strrchr(display_name,'.'); if (!section_name) { section_ID = 0; return;} for (;is_zip_suffix(section_name) && section_name != display_name;) for(section_name--;section_name != display_name && *section_name != '.';section_name --); if (section_name == display_name) {section_ID = 0; return;} section_ID = section_translate_c_to_n(++section_name); //if(!section_ID) printf("%s\n",display_name); } inline ManItem::~ManItem() { if(file_name) free(file_name); } char * ManItem::get_display_name(char * buffer) { char * p2 = buffer; for(char * p = display_name;p+1 != section_name && *p != '\0';) *buffer++ = *p++; *buffer = '\0'; return p2; } char * ManItem::get_section_name(char * buffer) { char * p2 = buffer; for(char * p = section_name;*p != '.' && *p != '\0';) *buffer++ = *p++; *buffer = '\0'; return p2; } int ManItem::get_section_ID() {return section_ID;} void * ManItem::get_man_path() {return (void *)man_path;} void ManItem::active_man_page(void) { int i; int len; char buffer[2*BUFFER_SIZE]; char loc_name[BUFFER_SIZE]; char buffer2[BUFFER_SIZE]; switch ((int)context->get_value("show_mode")) { case 0: sprintf(buffer,"%s -T '%s manual page' -n GMan -e man ", (char*)context->get_value("xterm_command"), get_display_name(buffer1)); len = strlen(buffer); attach(buffer+len,man_path->GetPath(),file_name); //g_warning(buffer); if(!fork()) { //printf(buffer); system(buffer); _exit(0); } break; case 1: sprintf(loc_name," ~/.gman.%s.ps ",get_display_name(buffer1)); sprintf(buffer,"man -t "); len = strlen(buffer); attach(buffer+len,man_path->GetPath(),file_name); strcat(buffer," >> "); strcat(buffer,loc_name); strcat(buffer," ; "); strcat(buffer,(char*)context->get_value("gv_command")); strcat(buffer,loc_name); strcat(buffer," ; rm "); strcat(buffer,loc_name); //g_warning(buffer); if(!fork()) { //printf(buffer); system(buffer); _exit(0); } break; /* case 2: sprintf(loc_name," ~/.gman.%s.html ",get_display_name(buffer1)); if(strstr(file_name,".gz")) sprintf(buffer,"gunzip -c "); else sprintf(buffer,"cat "); len = strlen(buffer); attach(buffer+len,man_path->GetPath(),file_name); strcat(buffer," > ~/.gman.tmp ;"); strcat(buffer," man2html ~/.gman.tmp -M "); strcat(buffer,(char*)context->get_value("cgi_location")); strcat(buffer," -H "); strcat(buffer,(char*)context->get_value("cgi_host")); strcat(buffer," >> "); strcat(buffer,loc_name); strcat(buffer," ; "); strcat(buffer,(char*)context->get_value("browser_command")); strcat(buffer,loc_name); strcat(buffer," ; rm ~/.gman.tmp ; sleep 120; rm "); strcat(buffer,loc_name); g_warning(buffer); if(!fork()) { //printf(buffer); system(buffer); _exit(0); } break; */ case 2: sprintf(loc_name," ~/.gman.%s.html ",get_display_name(buffer1)); //g_warning(loc_name); strcpy(buffer,"gman.cgi "); strcat(buffer," "); strcat(buffer,get_section_name(buffer2)); strcat(buffer," "); strcat(buffer,get_display_name(buffer2)); strcat(buffer," >> "); strcat(buffer,loc_name); strcat(buffer," ; "); strcat(buffer,(char*)context->get_value("browser_command")); //if (strstr((char*)context->get_value("browser_command"),"mozilla")) strcat(buffer," -chrome "); strcat(buffer,loc_name); strcat(buffer," ; sleep 120; rm "); strcat(buffer,loc_name); //g_warning(buffer); if(!fork()) { //printf(buffer); system(buffer); _exit(0); } break; case 3: sprintf(buffer,(char*)context->get_value("browser_command")); len = strlen(buffer); strcat(buffer," \"http://"); strcat(buffer,(char*)context->get_value("cgi_host")); strcat(buffer,(char*)context->get_value("cgi_location")); strcat(buffer,"?"); strcat(buffer,get_section_name(loc_name)); strcat(buffer,"+"); strcat(buffer,get_display_name(loc_name)); strcat(buffer,"\""); //g_warning(buffer); if(!fork()) { //printf(buffer); system(buffer); _exit(0); } break; default: if(context->get_value("show_warning")) g_print("unexpected \'show_mode\' : %d ",(int)context->get_value("show_mode")); return; } //g_warning(buffer); return; } /************************* init global data ************************/ /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */ 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 section_translate_c_to_n(const char *c) { int i; for(i=0;sections[i].name && strncmp(sections[i].name,c,sections[i].n);i++); if(sections[i].name == NULL) return 0; // no match return 1<get_display_name(buffer1),(*b)->get_display_name(buffer2))); } /* int ItemMatch(char * name) { int i; for (i=0;idisplay_name)>0 ;i++); return (i >= item_list_count)? i-1:i; } */ gman-0.9.3/mandata.h0100644000311700000120000000223407472365646012734 0ustar wxkwheel/********************** modified from t2.c *******************/ /********************* kman.h ********************************/ #include "list.h" #ifndef _KMAN_H #define _KMAN_H #define MAX_MAN_SECTION 15 #define BUFFER_SIZE 200 class ManPath; class ManItem; class ManPath { private: char * path_name; List * section[MAX_MAN_SECTION]; //1:2:3:4:5:6:7:8:9:tcl:n:l:p:o private: int LoadManSubPath(char *); public: int active; ManPath(char * path_name); ~ManPath(); int LoadManPath(char *); const char * GetPath(); int GetSize(int section_ID); int GetItems(int section_ID, ManItem **buffer); ManItem * search_man_item(char * name, char * section); }; class ManItem { public: ManItem(ManPath *, char * file_name); ~ManItem(); char * get_display_name(char * buffer); char * get_section_name(char * buffer); int get_section_ID(); void * get_man_path(); void active_man_page(); private: ManPath * man_path; char * file_name; char * display_name; char * section_name; int section_ID; }; //int ItemMatch(char * name); int man_item_compare(ManItem **,ManItem **); void attach (char *dest, const char *dirname, const char *name); #endif /* _KMAN_H */ gman-0.9.3/mandatadef.h0100644000311700000120000000054607472365646013417 0ustar wxkwheelstruct data_pair { char * name; int n; }; #define MAX_MAN_SECTION 15 data_pair sections[]= { {"1",1}, {"2",1}, {"3",1}, {"4",1}, {"5",1}, {"6",1}, {"7",1}, {"8",1}, {"l",1}, {"n",1}, {"9",1}, {"tcl",3}, {"p",1}, {"o",1}, {NULL,0} }; data_pair suffix[]= { {".gz",3}, {".bz2",4}, {".z",2}, {".Z",2}, {".F",2}, {".Y",2}, {NULL,0} }; gman-0.9.3/menu.c0100644000311700000120000006024307472443765012271 0ustar wxkwheel/********************** modified from t2.c *******************/ /********************* menu.c ********************************/ #include #include #include #include #ifdef SYS_DIR #include #else #ifdef NDIR #include #else #include #endif #endif #include #include #include #include #include #include #include "mandata.h" #include "util.h" #include "gman.h" #include "list.h" #include "task.h" #include "window2.h" #include "taskfunc.h" static int print_hello(GtkWidget *w, gpointer data); static int test_callback(GtkWidget *w, gpointer data); static int window_resize_callback(GtkWidget *w, GtkAllocation *size, gpointer data); static int section_policy_callback(GtkWidget *w, gpointer data); static int section_select_callback(GtkWidget *w, gpointer data); static int status_bar_callback (GtkWidget *widget, gpointer data); static int search_mode_callback (GtkWidget *widget, gpointer data); static int show_mode_callback(GtkWidget *w, gpointer data); static void app_quit(GtkWidget *w, gpointer data); static void select_row_callback(GtkWidget *, gint, gint, GdkEventButton *, gpointer); static void select_row_callback3(GtkWidget *, gint, gint, GdkEventButton *, gpointer); static void entry_activate_callback(GtkWidget *,gpointer); static void entry_changed_callback(GtkWidget *,gpointer); static void window_help_about_callback (GtkWidget *widget, gpointer data); static void entry4_activate_callback(GtkWidget *,gpointer); static void entry4_changed_callback(GtkWidget *,gpointer); static int button_clicked_callback(GtkWidget *,gpointer); #define MAX_PATHS 10 #define MENU_DISPLAY_POSITION 201 #define MENU_NEXT_POSITION 202 #define _(string) gettext(string) static GtkItemFactoryEntry menu_items[] = { {"/_File", NULL, NULL, 0, ""}, {"/File/_Quit", "Q", (void (*)(...))app_quit, 0, NULL}, {"/_Sections", NULL, NULL, 0, ""}, {"/Sections/tearoff1", NULL, NULL, 0, "" }, {"/Sections/_All", NULL, (void (*)(...))section_policy_callback, 0, ""}, {"/Sections/all _But", NULL, (void (*)(...))section_policy_callback, 1, "/Sections/All"}, {"/Sections/_Only", NULL, (void (*)(...))section_policy_callback, 2, "/Sections/All"}, {"/Sections/sep1", NULL, NULL, 0, ""}, {"/Sections/_1: User Commands", NULL, (void (*)(...))section_select_callback, 1<<0, ""}, {"/Sections/_2: System Calls", NULL, (void (*)(...))section_select_callback, 1<<1, ""}, {"/Sections/_3: Subroutines", NULL, (void (*)(...))section_select_callback, 1<<2, ""}, {"/Sections/_4: Devices", NULL, (void (*)(...))section_select_callback, 1<<3, ""}, {"/Sections/_5: File Formats", NULL, (void (*)(...))section_select_callback, 1<<4, ""}, {"/Sections/_6: Games", NULL, (void (*)(...))section_select_callback, 1<<5, ""}, {"/Sections/_7: Miscellaneous", NULL, (void (*)(...))section_select_callback, 1<<6, ""}, {"/Sections/_8: Sys.Administration",NULL, (void (*)(...))section_select_callback, 1<<7, ""}, {"/Sections/_l: Local", NULL, (void (*)(...))section_select_callback, 1<<8, ""}, {"/Sections/_n: New", NULL, (void (*)(...))section_select_callback, 1<<9, ""}, {"/_View", NULL, NULL, 0, ""}, {"/View/x_Term", "T", (void (*)(...))show_mode_callback, 0, ""}, {"/View/_GhostView", "G", (void (*)(...))show_mode_callback, 1, "/View/xTerm"}, {"/View/_LocalBrowse", "L", (void (*)(...))show_mode_callback, 2, "/View/xTerm"}, {"/View/_NetBrowse", "N", (void (*)(...))show_mode_callback, 3, "/View/xTerm"}, {"/_Options", NULL, NULL, 0, ""}, {"/Options/Status bar", NULL, (void (*)(...))status_bar_callback, 0, ""}, {"/Options/sep1", NULL, NULL, 0, ""}, {"/Options/_Index search", "I", (void (*)(...))search_mode_callback, 0, ""}, {"/Options/_Key word search", "K", (void (*)(...))search_mode_callback, 1, "/Options/Index search"}, {"/Options/sep2", NULL, NULL, 0, ""}, {"/Options/Man _Paths...", NULL, (void (*)(...))edit_paths_callback, 0, NULL}, // {"/Options/Test", NULL, (void (*)(...))test_callback, 0, NULL}, {"/_Help", NULL, NULL, 0, ""}, {"/_Help/About", NULL, GTK_SIGNAL_FUNC(window_help_about_callback),0,NULL} }; /********************* init_main_window *************************/ GtkWidget * clist; GtkWidget * entry; GtkWidget * clist3; GtkWidget * window; //main window GtkTooltips * tooltips; GtkWidget * section_buttons[MAX_MAN_SECTION]; GtkWidget * section_select[3]; GtkWidget * searching_mode_buttons[2]; GtkWidget * show_mode_buttons[4]; GtkWidget * status_bar_button; int signal_select_row; //used by select_row_callback() to decide whether to active man pages int signal_entry_change; //used by entry_changed_callback() to decide whether to refresh list int signal_menu_change; //used by menu_item callback to decide whether to take action or not Dictionary * man_paths; char * *man_items_buffer; int man_items_count; int clist_selected_row; List * man_paths_to_be_load; char * keyword; void updata_menu_buttons(int); void get_main_menu(GtkWidget *window, GtkWidget ** menubar) { int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]); GtkItemFactory *item_factory; GtkAccelGroup *accel_group; accel_group = gtk_accel_group_new(); /* This function initializes the item factory. Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU, or GTK_TYPE_OPTION_MENU. Param 2: The path of the menu. Param 3: A pointer to a gtk_accel_group. The item factory sets up the accelerator table while generating menus. */ item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "
", accel_group); /* This function generates the menu items. Pass the item factory, the number of items in the array, the array itself, and any callback data for the the menu items. */ gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL); /* Attach the new accelerator group to the window. */ gtk_accel_group_attach (accel_group, GTK_OBJECT (window)); if (menubar) /* Finally, return the actual menu bar created by the item factory. */ *menubar = gtk_item_factory_get_widget(item_factory, "
"); section_select[0] = gtk_item_factory_get_widget(item_factory, "/Sections/All"); section_select[1] = gtk_item_factory_get_widget(item_factory, "/Sections/all But"); section_select[2] = gtk_item_factory_get_widget(item_factory, "/Sections/Only"); section_buttons[0] = gtk_item_factory_get_widget(item_factory, "/Sections/1: User Commands"); section_buttons[1] = gtk_item_factory_get_widget(item_factory, "/Sections/2: System Calls"); section_buttons[2] = gtk_item_factory_get_widget(item_factory, "/Sections/3: Subroutines"); section_buttons[3] = gtk_item_factory_get_widget(item_factory, "/Sections/4: Devices"); section_buttons[4] = gtk_item_factory_get_widget(item_factory, "/Sections/5: File Formats"); section_buttons[5] = gtk_item_factory_get_widget(item_factory, "/Sections/6: Games"); section_buttons[6] = gtk_item_factory_get_widget(item_factory, "/Sections/7: Miscellaneous"); section_buttons[7] = gtk_item_factory_get_widget(item_factory, "/Sections/8: Sys.Administration"); section_buttons[8] = gtk_item_factory_get_widget(item_factory, "/Sections/l: Local"); section_buttons[9] = gtk_item_factory_get_widget(item_factory, "/Sections/n: New"); searching_mode_buttons[0] = gtk_item_factory_get_widget(item_factory, "/Options/Index search"); searching_mode_buttons[1] = gtk_item_factory_get_widget(item_factory, "/Options/Key word search"); show_mode_buttons[0] = gtk_item_factory_get_widget(item_factory, "/View/xTerm"); show_mode_buttons[1] = gtk_item_factory_get_widget(item_factory, "/View/GhostView"); show_mode_buttons[2] = gtk_item_factory_get_widget(item_factory, "/View/LocalBrowse"); show_mode_buttons[3] = gtk_item_factory_get_widget(item_factory, "/View/NetBrowse"); status_bar_button = gtk_item_factory_get_widget(item_factory, "/Options/Status bar"); // gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_buttons[4]),1); updata_menu_buttons(0); } /*flag = 0 means not to invoke call backs when changing the states of buttons.*/ void updata_menu_buttons(int flag) { int i,j,k,k2; k = (int)context->get_value("display_section_policy"); if(k>0 && k<=2) if(!((GtkCheckMenuItem*)(section_select[k]))->active){ if(!flag) signal_menu_change++; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_select[k]),1); } k = (int)context->get_value("display_section"); for (i = 0;i<10;i++) if(!(k&(1<active)) { if(!flag) signal_menu_change++; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_buttons[i]),k&(1<get_value("searching_mode"); if(k>0 && k<=1) if(!(((GtkCheckMenuItem*)(searching_mode_buttons[k]))->active)) { if(!flag) signal_menu_change++; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(searching_mode_buttons[k]),1); } k = (int)context->get_value("show_mode"); if(k>0 && k<=3) if(!(((GtkCheckMenuItem*)(show_mode_buttons[k]))->active)) { if(!flag) signal_menu_change++; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(show_mode_buttons[k]),1); } k2 = (int)context->get_value("show_status_bar"); i = k2&(1<active); if((i&&!j) || (!i&&j)) { if(!flag) signal_menu_change++; gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(status_bar_button),i); } gtk_widget_hide(status_bar_button); } static GtkWidget *index_search_vbox; static GtkWidget *keyword_search_vbox; static GtkWidget *hbox4; static GtkWidget *hbox_status; static GtkWidget *entry4; GtkWidget *search_button; GtkWidget *stop_button; static GtkWidget *statusbar1; static GtkWidget *statusbar2; static void updata_widget_show(int flag) { int k,k2; k = (int)context->get_value("searching_mode"); k2 = (int)context->get_value("show_status_bar"); if(k2&(1<get_value("h_size"), (int)context->get_value("v_size")); gtk_widget_set_usize(GTK_WIDGET(window),200,150); main_vbox = gtk_vbox_new(FALSE, 1); gtk_container_border_width(GTK_CONTAINER(main_vbox), 1); gtk_container_add(GTK_CONTAINER(window), main_vbox); gtk_widget_show(main_vbox); get_main_menu(window, &menubar); gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0); gtk_widget_show(menubar); gtk_signal_connect(GTK_OBJECT(window),"size_allocate",GTK_SIGNAL_FUNC(window_resize_callback),NULL); //keyword_search_vbox keyword_search_vbox = gtk_vbox_new(FALSE,1); gtk_box_pack_start(GTK_BOX(main_vbox), keyword_search_vbox, TRUE, TRUE, 0); hbox4 = gtk_hbox_new (FALSE, 1); gtk_object_set_data (GTK_OBJECT (window), "hbox4", hbox4); gtk_box_pack_start (GTK_BOX (keyword_search_vbox), hbox4, FALSE, TRUE, 0); gtk_widget_show (hbox4); stop_button = gtk_button_new_with_label ("Stop"); gtk_object_set_data (GTK_OBJECT (window), "stop_button", stop_button); gtk_widget_set_sensitive(stop_button,0); gtk_signal_connect (GTK_OBJECT(stop_button),"clicked",(GtkSignalFunc)button_clicked_callback,(void*)1); gtk_widget_show (stop_button); gtk_box_pack_start (GTK_BOX (hbox4), stop_button, FALSE, TRUE, 0); gtk_widget_set_usize (stop_button, 40, -2); entry4 = gtk_entry_new (); gtk_object_set_data (GTK_OBJECT (window), "entry4", entry4); gtk_widget_show (entry4); gtk_tooltips_set_tip (tooltips, entry4, "Key word search", NULL); gtk_box_pack_start (GTK_BOX (hbox4), entry4, TRUE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(entry4), "activate", GTK_SIGNAL_FUNC(entry4_activate_callback),NULL); gtk_signal_connect(GTK_OBJECT(entry4), "changed", GTK_SIGNAL_FUNC(entry4_changed_callback),NULL); search_button = gtk_button_new_with_label ("Search"); gtk_object_set_data (GTK_OBJECT (window), "search_button", search_button); gtk_widget_set_sensitive(search_button,0); gtk_signal_connect (GTK_OBJECT(stop_button),"clicked",(GtkSignalFunc)button_clicked_callback,(void*)2); gtk_widget_show (search_button); gtk_box_pack_start (GTK_BOX (hbox4), search_button, FALSE, TRUE, 0); gtk_widget_set_usize (search_button, 60, -2); clist3 = gtk_clist_new_with_titles( 3, titles2); swindow2 = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow2), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_clist_set_column_width(GTK_CLIST(clist3),0,100); gtk_clist_set_selection_mode(GTK_CLIST(clist3),GTK_SELECTION_SINGLE); gtk_clist_column_titles_passive(GTK_CLIST(clist3)); gtk_clist_set_column_auto_resize (GTK_CLIST(clist3),2,1); gtk_container_add (GTK_CONTAINER (swindow2), clist3); gtk_box_pack_start (GTK_BOX (keyword_search_vbox), swindow2, TRUE, TRUE, 0); gtk_widget_show_all(GTK_WIDGET(swindow2)); gtk_signal_connect(GTK_OBJECT(clist3),"select_row", GTK_SIGNAL_FUNC(select_row_callback3),NULL); //index_search_vbox index_search_vbox = gtk_vbox_new(FALSE,1); gtk_box_pack_start(GTK_BOX(main_vbox), index_search_vbox, TRUE, TRUE, 0); entry = gtk_entry_new_with_max_length (50); clist = gtk_clist_new_with_titles( 2, titles); gtk_signal_connect(GTK_OBJECT(entry), "activate", GTK_SIGNAL_FUNC(entry_activate_callback), (gpointer)clist); gtk_signal_connect(GTK_OBJECT(entry), "changed", GTK_SIGNAL_FUNC(entry_changed_callback), (gpointer)clist); gtk_box_pack_start (GTK_BOX (index_search_vbox), entry, FALSE, TRUE, 0); gtk_tooltips_set_tip (tooltips, entry, "index search", NULL); gtk_widget_show(entry); swindow = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_clist_set_column_width(GTK_CLIST(clist),0,200); gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE); gtk_clist_column_titles_passive(GTK_CLIST(clist)); gtk_container_add (GTK_CONTAINER (swindow), clist); gtk_box_pack_start (GTK_BOX (index_search_vbox), swindow, TRUE, TRUE, 0); gtk_signal_connect(GTK_OBJECT(clist),"select_row", GTK_SIGNAL_FUNC(select_row_callback),NULL); focus = entry; gtk_widget_grab_focus (focus); gtk_widget_show_all (swindow); hbox_status = gtk_hbox_new (FALSE, 0); gtk_object_set_data (GTK_OBJECT (window), "hbox_status", hbox_status); gtk_box_pack_start (GTK_BOX (main_vbox), hbox_status, FALSE, TRUE, 0); updata_widget_show(0); statusbar1 = gtk_statusbar_new (); gtk_object_set_data (GTK_OBJECT (window), "statusbar1", statusbar1); gtk_widget_show (statusbar1); gtk_box_pack_start (GTK_BOX (hbox_status), statusbar1, TRUE, TRUE, 0); statusbar2 = gtk_statusbar_new (); gtk_object_set_data (GTK_OBJECT (window), "statusbar2", statusbar2); gtk_widget_show (statusbar2); gtk_box_pack_start (GTK_BOX (hbox_status), statusbar2, FALSE, TRUE, 0); } /******************* tools functions ******************/ int search_array_for_text(char ** array, int count, char * text) { int i; for (i=0;i0 ;i++); return (i >= count)? i-1:i; } /******************* call backs ***********************/ void select_row_callback(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { ManItem * item; if(signal_select_row>0) {signal_select_row--;return;} item = (ManItem*) gtk_clist_get_row_data(GTK_CLIST(widget),row); item->active_man_page(); signal_entry_change++; gtk_entry_set_text(GTK_ENTRY(entry),man_items_buffer[row]); } void select_row_callback3(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) { ManItem * item; if(signal_select_row>0) {signal_select_row--;return;} item = (ManItem*) gtk_clist_get_row_data(GTK_CLIST(widget),row); if(item) item->active_man_page(); } void entry_activate_callback(GtkWidget * w,gpointer data) { int i; GtkWidget * clist = (GtkWidget *)data; i = search_array_for_text(man_items_buffer, man_items_count, gtk_entry_get_text(GTK_ENTRY(w))); if (i == -1) return; gtk_clist_moveto(GTK_CLIST(clist),i,0,0.1,0.0); GTK_CLIST(clist)->focus_row = i; gtk_clist_select_row(GTK_CLIST(clist),i,0); } void entry_changed_callback(GtkWidget * w,gpointer data) { int i; GtkWidget * clist = (GtkWidget *)data; if(signal_entry_change>0) {signal_entry_change--;return;} i = search_array_for_text(man_items_buffer, man_items_count, gtk_entry_get_text(GTK_ENTRY(w))); if (i == -1) return; signal_select_row++; gtk_clist_moveto(GTK_CLIST(clist),i,0,0.1,0.0); GTK_CLIST(clist)->focus_row = i; gtk_clist_select_row(GTK_CLIST(clist),i,0); } static int print_hello(GtkWidget *w, gpointer data) { if(signal_menu_change>0) {signal_menu_change--;return 1;} g_message("Hello, World! %x\n",data); return 0; } static int print_page(GtkWidget *w, gpointer data) { if(signal_menu_change>0) {signal_menu_change--;return 1;} g_message("Hello, World! %x\n",data); return 0; } static int test_callback(GtkWidget *w, gpointer data) { int i,j; if(signal_menu_change>0) {signal_menu_change--;return 1;} j = man_paths->get_size(); for(i = 0;iget_value(i))); delete (man_paths); init_man_data(); return 0; } static int section_policy_callback(GtkWidget *w, gpointer data) { // static int signal; int k,k2; k2 = (int) data; if(!((GtkCheckMenuItem*)(section_select[k2]))->active) return 1; // g_message("Hello, World! %x\n signal = %d",data,signal_menu_change); if(signal_menu_change>0) {signal_menu_change--;return 1;} //if(!signal) {signal++;return 1;} //signal--; k = (int) context->get_value("display_section_policy"); if(k == k2) return 1; pthread_mutex_lock(&context_lock); context->set_value("display_section_policy","int",(void*)k2); pthread_mutex_unlock(&context_lock); task_set_active(task_extract_man_data); task_set_active(task_add_data_to_clist); } static int section_select_callback(GtkWidget *w, gpointer data) { int var; if(signal_menu_change>0) {signal_menu_change--;return 1;} pthread_mutex_lock(&context_lock); var = (int)context->get_value("display_section"); var ^= (int)data; context->set_value("display_section","int",(void*)var); if (context->get_value("display_section_policy")) { task_set_active(task_extract_man_data); task_set_active(task_add_data_to_clist); } pthread_mutex_unlock(&context_lock); // g_message("Hello, World! %x\n",data); } static void app_quit(GtkWidget *w, gpointer data) { // g_message("Bye, World! %x\n",data); char buffer[1024],*p; FILE * fd; int i,j; p = buffer; j = man_paths->get_size(); for (i = 0;iget_name(i)); for(;*p;p++); } context->set_value("man_paths","char*",my_strdup(buffer)); attach(buffer,getenv("HOME"),".gman"); if((fd = fopen(buffer,"w"))) { context->save(fd,"automatically made by G-man"); fclose(fd); } // context->save(stdout,"automatically made by G-man"); gtk_exit((int)data); } static int window_resize_callback(GtkWidget *w, GtkAllocation * size, gpointer data) { /* g_message("x = %d, y = %d, width = %d, height = %d, data = %x\n", size->x,size->y,size->width,size->height,data); */ context->set_value("h_size","int",(void*)size->width); context->set_value("v_size","int",(void*)size->height); return 0; } static void window_help_about_callback (GtkWidget *widget, gpointer data) { const gchar *authors[] = {"Xinkai Wang ", NULL }; static GtkWidget *about_window = NULL; if (!about_window) { GtkWidget *button; GdkFont *font; about_window = gtk_dialog_new (); gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_MOUSE); gtk_window_set_title (GTK_WINDOW (about_window), _("About gman")); gtk_signal_connect (GTK_OBJECT (about_window), "delete_event", GTK_SIGNAL_FUNC (gtk_false), NULL); gtk_signal_connect (GTK_OBJECT (about_window), "destroy", (GtkSignalFunc) gtk_widget_destroyed, &about_window); button = gtk_button_new_with_label (_("Close")); gtk_widget_show (button); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->action_area), button, TRUE, TRUE, 0); gtk_signal_connect_object (GTK_OBJECT (button), "clicked", (GtkSignalFunc) gtk_widget_destroy, GTK_OBJECT (about_window)); gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (about_window)->vbox), 5); /* TODO: we need a logo ;) */ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox), gtk_label_new ("Gman - version " VERSION), FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox), gtk_label_new ("Copyright (C) 1999 Xinkai Wang"), FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox), gtk_label_new ("Comments and suggestions are extremely welcomed!"), FALSE, FALSE, 5); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox), gtk_label_new ("Web: http://homex.coolconnect.com/user/xkwang/gman/"), FALSE, FALSE, 5); if (!GTK_WIDGET_VISIBLE (about_window)) gtk_widget_show_all (about_window); else gtk_widget_hide (about_window); } } static int status_bar_callback (GtkWidget *widget, gpointer data) { int k,k2; if(signal_menu_change>0) {signal_menu_change--;return 1;} k2 = (int) context->get_value("show_status_bar"); k = (int) context->get_value("searching_mode"); if(((GtkCheckMenuItem*)(status_bar_button))->active) k2 = k2 | (1<set_value("show_status_bar","int",(void*)k2); pthread_mutex_unlock(&context_lock); updata_widget_show(0); return 0; } static int search_mode_callback (GtkWidget *widget, gpointer data) { int k,k2; k2 = (int) data; if(!((GtkCheckMenuItem*)(searching_mode_buttons[k2]))->active) return 1; if(signal_menu_change>0) {signal_menu_change--;return 1;} //if(!signal) {signal++;return 1;} //signal--; k = (int) context->get_value("searching_mode"); if(k == k2) return 1; pthread_mutex_lock(&context_lock); context->set_value("searching_mode","int",(void*)k2); pthread_mutex_unlock(&context_lock); updata_widget_show(0); updata_menu_buttons(0); return 0; } static int show_mode_callback (GtkWidget *widget, gpointer data) { int k,k2; k2 = (int) data; if(!((GtkCheckMenuItem*)(show_mode_buttons[k2]))->active) return 1; if(signal_menu_change>0) {signal_menu_change--;return 1;} //if(!signal) {signal++;return 1;} //signal--; k = (int) context->get_value("show_mode"); if(k == k2) return 1; pthread_mutex_lock(&context_lock); context->set_value("show_mode","int",(void*)k2); pthread_mutex_unlock(&context_lock); //updata_widget_show(0); //updata_menu_buttons(0); return 0; } static void entry4_activate_callback(GtkWidget *w,gpointer data) { keyword = gtk_entry_get_text(GTK_ENTRY(entry4)); task_set_active(task_key_word_search); } static void entry4_changed_callback(GtkWidget *w,gpointer data) { char * tmp; tmp = gtk_entry_get_text(GTK_ENTRY(entry4)); gtk_widget_set_sensitive(search_button,strlen(tmp) >= 3); } static int button_clicked_callback(GtkWidget * w,gpointer data) { int i = (int) data; switch (i) { case 1: task_set_stop(task_key_word_search);break; case 2: task_set_active(task_key_word_search);break; } } gman-0.9.3/menu.h0100644000311700000120000000073007472365646012272 0ustar wxkwheel/********************* menu.h *********************/ #ifndef _MENU_H #define _MENU_H #include "task.h" #include void init_main_window(GtkWidget *); extern GtkWidget * clist; extern GtkWidget * clist3; extern List * man_paths_to_be_load; extern GtkTooltips * tooltips; extern Dictionary * man_paths; extern char * *man_items_buffer; extern int man_items_count; extern char *keyword; extern GtkWidget *search_button; extern GtkWidget *stop_button; #endif gman-0.9.3/msort.c0100644000311700000120000000563007472365646012471 0ustar wxkwheel/* An alternative to qsort, with an identical interface. This file is part of the GNU C Library. Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc. Written by Mike Haertel, September 1988. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include static void msort_with_tmp __P ((void *b, size_t n, size_t s, __compar_fn_t cmp, char *t)); static void msort_with_tmp (b, n, s, cmp, t) void *b; size_t n; size_t s; __compar_fn_t cmp; char *t; { char *tmp; char *b1, *b2; size_t n1, n2; if (n <= 1) return; n1 = n / 2; n2 = n - n1; b1 = b; b2 = (char *) b + (n1 * s); msort_with_tmp (b1, n1, s, cmp, t); msort_with_tmp (b2, n2, s, cmp, t); tmp = t; if (s == OPSIZ && (b1 - (char *) 0) % OPSIZ == 0) /* We are operating on aligned words. Use direct word stores. */ while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2) <= 0) { --n1; *((op_t *) tmp)++ = *((op_t *) b1)++; } else { --n2; *((op_t *) tmp)++ = *((op_t *) b2)++; } } else while (n1 > 0 && n2 > 0) { if ((*cmp) (b1, b2) <= 0) { tmp = (char *) __mempcpy (tmp, b1, s); b1 += s; --n1; } else { tmp = (char *) __mempcpy (tmp, b2, s); b2 += s; --n2; } } if (n1 > 0) memcpy (tmp, b1, n1 * s); memcpy (b, t, (n - n2) * s); } void qsort (b, n, s, cmp) void *b; size_t n; size_t s; __compar_fn_t cmp; { const size_t size = n * s; if (size < 1024) /* The temporary array is small, so put it on the stack. */ msort_with_tmp (b, n, s, cmp, __alloca (size)); else { /* It's somewhat large, so malloc it. */ int save = errno; char *tmp = malloc (size); if (tmp == NULL) { /* Couldn't get space, so use the slower algorithm that doesn't need a temporary array. */ extern void _quicksort __P ((void *const __base, size_t __nmemb, size_t __size, __compar_fn_t __compar)); _quicksort (b, n, s, cmp); } else { msort_with_tmp (b, n, s, cmp, tmp); free (tmp); } __set_errno (save); } } gman-0.9.3/t2.c0100644000311700000120000005302007472365646011646 0ustar wxkwheel/********************** 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; } gman-0.9.3/task.c0100644000311700000120000001010607472365646012261 0ustar wxkwheel/************************ task.c ***************************/ /*********************** 1999.6.21 *************************/ #include "task.h" #include #include #include struct _task_group { pthread_t thread; pthread_attr_t attr; pthread_mutex_t lock; int state; List * tasks; }; struct _task { TaskGroup * task_group; pthread_mutex_t lock; int state; float priority; TaskRunFunc task_run_func; gpointer user_data; List * signals[2]; //signal quenes, 1 for synchronous signals, 0 for unsynchronous signals }; static void * task_group_running(TaskGroup *); static void task_group_set_active(TaskGroup *); TaskGroup * task_group_new() { int retcode; TaskGroup * task_group = (TaskGroup*)g_malloc(sizeof(TaskGroup)); task_group->tasks = new List; task_group->state = 0; pthread_attr_init(&(task_group->attr)); pthread_attr_setdetachstate(&(task_group->attr), 1); pthread_mutex_init(&task_group->lock,NULL); //retcode = pthread_create(&task_group->thread, NULL, (void*(*)(void*))my_thread_running, (void *) task_group); //if (retcode != 0) g_error("my_thread_new:thread creation failed %d\n", retcode); return task_group; } Task * task_new(TaskGroup * task_group, float priority, TaskRunFunc task_func, gpointer data) { int i,j,k; Task * task; g_return_val_if_fail((priority>0.0 && priority <1.0)&&(task_group != NULL)&&(task_func != NULL),(Task*)NULL); task = (Task *)g_malloc(sizeof(Task)); pthread_mutex_init(&task->lock,(const pthread_mutexattr_t *)NULL); task->priority = priority; task->state = 0; task->task_group = task_group; task->task_run_func = task_func; task->user_data = data; task->signals[0] = new List; task->signals[1] = new List; pthread_mutex_lock(&task_group->lock); j = task_group->tasks->get_size(); for(i = 0;i((Task*)task_group->tasks->get_item(i))->priority;i++); task_group->tasks->insert_item(i,(void*)task); pthread_mutex_unlock(&task_group->lock); return task; } void task_signal_send(Task * task, int signal) { g_return_if_fail(task != NULL); pthread_mutex_lock(&task->lock); task->signals[signal&1]->add_item((void*)signal); pthread_mutex_unlock(&task->lock); task_group_set_active(task->task_group); } void task_set_active(Task * task) { task_signal_send(task,TASK_START); } void task_set_stop(Task * task) { task_signal_send(task,TASK_STOP); } //let the task itself to decide wether to stop or not //of the task don't want to be wake up any more, it will return 0, //otherwise 1. static void task_group_set_active(TaskGroup * task_group) { int retcode; pthread_mutex_lock(&task_group->lock); if(!task_group->state) { task_group->state |= 1; retcode = pthread_create(&task_group->thread, &task_group->attr, (void*(*)(void*))task_group_running, (void *) task_group); if (retcode != 0) g_error("thread creation failed %d\n", retcode); } pthread_mutex_unlock(&task_group->lock); } static void * task_group_running(TaskGroup * task_group) { int i,j; int have_task; int state,k; Task * task; do { have_task = 0; task = (Task *)NULL; int flag; pthread_mutex_lock(&task_group->lock); j = task_group->tasks->get_size(); for(i = 0; itasks->get_item(i))->signals[0]->get_size()) { flag = ((int)task->signals[0]->get_item(0) & ~1) | (task->state & 1); task->signals[0]->delete_item(0); have_task++; } else if (task->state & TASK_RUNNING) { flag = task->state & TASK_RUNNING; have_task++; } else if (task->signals[1]->get_size()) { flag = ((int)task->signals[1]->get_item(1) & ~1); task->signals[1]->delete_item(0); have_task++; } } pthread_mutex_unlock(&task_group->lock); if(have_task) { // printf("init state = %x\n",task->state); state = (*task->task_run_func)(flag,task->user_data); if(state) task->state |= TASK_RUNNING; else task->state &= ~TASK_RUNNING; // printf("return state = %x\n",task->state); } } while (have_task); pthread_mutex_lock(&task_group->lock); task_group->state &= ~TASK_RUNNING; pthread_mutex_unlock(&task_group->lock); return 0; } gman-0.9.3/task.h0100644000311700000120000000125207472365646012270 0ustar wxkwheel/************************ task.h ***************************/ /************************ 1999.6.21 ************************/ #ifndef _TASK_H #define _TASK_H #include #include "list.h" typedef enum { TASK_RUNNING = 1 << 0, TASK_START = 1 << 1, TASK_STOP = 1 << 2, } MyTaskRunningFlags; typedef struct _task_group TaskGroup; typedef struct _task Task; typedef int (* TaskRunFunc) (int flag, gpointer data); TaskGroup * task_group_new(); Task * task_new(TaskGroup * thread, float priority, TaskRunFunc task_func, gpointer data); void task_signal_send(Task * task, int signal); void task_set_active(Task * task); void task_set_stop(Task * task); #endif gman-0.9.3/taskfunc.c0100644000311700000120000002453407472365646013147 0ustar wxkwheel#include #include "taskfunc.h" #include "menu.h" #include "mandata.h" #include "context.h" #include "util.h" #include "gman.h" #include #include "window2.h" #include #include #include #include #include //#include /********************* init_man_data *************************/ int init_man_data() { ManPath * path; char * path_name,*p1,*p2; int end = 0; man_paths = new Dictionary; path_name = my_strdup((char*)context->get_value("man_paths")); p1 = path_name; while(!end) { p2 = strchr(p1,(int)':'); if(p2 == NULL) end++; else *p2 = '\0'; man_paths->add_item(my_strdup(p1),(void*)( new ManPath(p1))); p1 = p2+1; } if(path_name) free (path_name); return 0; } int extract_man_data() { ManItem ** buffer; int i,j,count; int display_section_ID; pthread_mutex_lock(&context_lock); switch ((int)context->get_value("display_section_policy")) { case 0: display_section_ID = ~0;break; case 1: display_section_ID = ~(int)(context->get_value("display_section"));break; case 2: display_section_ID = (int)context->get_value("display_section"); break; default: fprintf(stderr,"warning: init_man_data: \"display_section_policy\" " "have invalid value %d",context->get_value("display_section_policy")); display_section_ID = ~0; } pthread_mutex_unlock(&context_lock); if(man_items_count) free(man_items_buffer); j = man_paths->get_size(); for(i = man_items_count = 0;iget_value(i)))->GetSize(display_section_ID); buffer = (ManItem**)malloc(sizeof(ManItem*)*man_items_count); man_items_buffer = (char**) buffer; for(i = count = 0;iget_value(i)))->GetItems(display_section_ID,buffer+count); if( count != man_items_count) exit(1); if(context->get_value("debuging")) printf("count = %d\n",count); qsort((void *)buffer,count,sizeof(ManItem*),(int(*)(const void*,const void*))&man_item_compare); if(context->get_value("debuging")) printf("count = %d, qsort end.\n",count); return 0; } int add_data_to_clist(int flag) { gchar *text[2]; static int i; int j,k; ManItem ** buffer; static char ** pointer; char a[100],b[20]; int display_section_ID; text[0] = a; text[1] = b; buffer = (ManItem**) man_items_buffer; pthread_mutex_lock(>k_lock); if(flag & TASK_START) { i = 0; pointer = man_items_buffer; gtk_clist_clear(GTK_CLIST(clist)); } gtk_clist_freeze(GTK_CLIST(clist)); for (j = 0;j<100 & i< man_items_count;i++,j++) { buffer[i]->get_display_name(a); buffer[i]->get_section_name(b); gtk_clist_append(GTK_CLIST(clist),text); gtk_clist_set_row_data(GTK_CLIST(clist),i,(gpointer)buffer[i]); gtk_clist_get_text(GTK_CLIST(clist),i,0,pointer++); } gtk_clist_thaw(GTK_CLIST(clist)); pthread_mutex_unlock(>k_lock); //pointer = man_items_display_name; //for(int i = 0;iget_size()) return 0; pthread_mutex_lock(&loading_man_path_lock); c = (char*)man_paths_to_be_load->get_item(0); man_paths_to_be_load->delete_item(0); pthread_mutex_unlock(&loading_man_path_lock); p = new ManPath(c); i = man_paths->search_item(c); if (i == -1) { delete (p); g_warning("man path %s does not exist\n",c); return man_paths_to_be_load->get_size(); } // printf("loading... %d end\n",i); man_paths->set_value(i,(void*)p); if(clist2) { sprintf(buffer,"%d",p->GetSize(-1)); pthread_mutex_lock(>k_lock); gtk_clist_set_text(GTK_CLIST(clist2),i,2,buffer); pthread_mutex_unlock(>k_lock); } return man_paths_to_be_load->get_size(); } int is_blank(char c) {return (c==0x20||c==0x09)?1:0;} typedef enum { S_START, S_NAME, S_NAME_END1, S_NAME_END2, S_SECTION, S_SECTION_END1, S_SECTION_END2, S_MINUS, S_COMMENT_START, S_COMMENT } STATES; #define BUF_SIZE 400 static List * names; //the names returned are strdup() , need to free out side static char * comment; static char section[BUF_SIZE/4]; static int parser_whatis(int fd) { static int init = 0; int i,j,k,end; static char buffer[BUF_SIZE]; char a,b,c; if(!init) { names = new List; init ++; } names->delete_all(); i = 0; end = 0; STATES s = S_START; while(!end) { k = read(fd,&c,1); //g_print("%c",c,k); if(k == -1) g_error("key word task:reading from pipe:%s",g_strerror(errno)); if (k == 0 || c == 0x0a) { if (s == S_COMMENT) { buffer[i] = 0; // add items to clist //for(j = 0;jget_size();j++) g_print("%s , ",(char*)names->get_item(j)); //g_print("section = %s, \tcomment = %s\n",section,buffer); comment = buffer; } else if( s != S_START) { if(context->get_value("show_warning")) g_warning("parser error: unexpected end of %s",k?"line":"file"); comment = NULL; } end++; continue; } switch (s) { case S_START: if(!is_blank(c)) { s = S_NAME; i = 0; buffer[i++] = c; } break; case S_NAME: if( c == ',') { s = S_NAME_END1; buffer[i] = 0; names->add_item(my_strdup(buffer)); } else if(is_blank(c)) { s = S_NAME_END2; }else { buffer[i++] = c; } break; case S_NAME_END1: if(is_blank(c)) break; else if(c == '(') { s = S_SECTION; i = 0; } else { s = S_NAME; i = 0; buffer[i++] = c; } break; case S_NAME_END2: if(is_blank(c)) break; else if(c == '(') { buffer[i] = 0; names->add_item(my_strdup(buffer)); s = S_SECTION; i = 0; } else if(c == ',') { s = S_NAME_END1; buffer[i] = 0; names->add_item(my_strdup(buffer)); } else { s = S_NAME; buffer[i++] = c; } break; case S_SECTION: if(is_blank(c)) break; else if(c == ')') { s = S_SECTION_END1; if(i == 0) { g_warning("parser error: unknown format"); } else { buffer[i] = 0; strcpy(section,buffer); } } else buffer[i++] = c; break; case S_SECTION_END1: if(is_blank(c)) break; else if(c == '-') s = S_SECTION_END2; break; case S_SECTION_END2: if(is_blank(c)) s = S_COMMENT_START; else g_warning("parser error: unknwn format"); break; case S_COMMENT_START: if(!is_blank(c)) { s = S_COMMENT; i = 0; buffer[i++] = c; } break; case S_COMMENT: buffer[i++] = c; break; default: g_warning("parser error: unknow state"); } } //g_print("k = %d\n",k); return k; } List * keyword_search_list; static int key_word_search_taskfunc(int flag) { static int init = 0; static char * parameter; static int process_ID; static int pipes[2]; static List * paths; static char * path; static int pipe_active; // pipe is in active static int running; // pipe is in active static int counter; ManPath * man_path; ManItem * man_item; int i,j,k; char file_name[BUF_SIZE], buffer[BUF_SIZE]; char * text[3]; char * s; if(!init) { pipe_active = 0; running = 0; paths = new List(); keyword_search_list = new List(); init ++; } //g_print("task key-word search ...\n"); if((flag & (TASK_START|TASK_STOP)) && pipe_active) { //g_print("reset ...\n"); kill(process_ID,3); close(pipes[0]); pipe_active = 0; running = 0; gtk_widget_set_sensitive(stop_button,0); //paths->delete_all(); } if(flag & TASK_START) { //g_print("starting ... key = %s\n",keyword); running = 1; gtk_widget_set_sensitive(stop_button,1); paths->delete_all(); gtk_clist_clear(GTK_CLIST(clist3)); counter = 0; j = man_paths->get_size(); for(i = 0;iadd_item(man_paths->get_name(i)); } else if( !pipe_active ) { if(paths->get_size() == 0) { running = 0; gtk_widget_set_sensitive(stop_button,0); } else { path = (char*) paths->get_item(0); paths->delete_item(0); strcpy(buffer,"grep "); strcat(buffer,keyword); strcat(buffer," "); attach(file_name,path,"whatis"); strcat(buffer,file_name); strcat(buffer," "); g_return_val_if_fail(!pipe(pipes),0); process_ID = fork(); if(process_ID == -1) {g_warning("can not fork a new process");return 0;} if(process_ID == 0) { g_return_val_if_fail(close(pipes[0]) != -1,0);; close(1); g_return_val_if_fail(dup(pipes[1]) == 1,0); g_return_val_if_fail(close(pipes[1]) != -1,0); //write(1,"1234567890safdsfd%srfwfwefw",10); //fprintf(stderr,"%s\n",buffer); if(do_system_command(buffer,0));// g_warning("my_system returned a non-zero value!"); _exit(0); } close(pipes[1]); pipe_active ++; } } else { //running, pipe in active k = parser_whatis(pipes[0]); if((j = names->get_size())) { /* for(i = 0;iget_item(i)); g_print("(%s)",section); g_print(" - %s\n",comment); */ man_path = (ManPath*)man_paths->get_value(man_paths->search_item(path)); text[1] = section; text[2] = ""; for(i = 0;iget_item(i); if(s[0] == '/') s = strrchr(s, '/') + 1; man_item = (ManItem*)man_path->search_man_item(s,section); //g_print("point 1\n"); if(context->get_value("show_warning")) if (!man_item) g_warning("man item: %s (%s) could not found",names->get_item(i),section); text[0] = (char*)names->get_item(i); //g_print("point 2\n"); if(i == j-1) text[2] = comment; pthread_mutex_lock(>k_lock); gtk_clist_append(GTK_CLIST(clist3),text); gtk_clist_set_row_data(GTK_CLIST(clist3),counter++,(gpointer)man_item); pthread_mutex_unlock(>k_lock); } } if(k == 0) { close(pipes[0]); pipe_active = 0; //g_print("pipe closeing \n"); } } return running; } /******************* init thread **********************/ Task *task_init_man_data; Task *task_extract_man_data; Task *task_add_data_to_clist; Task *task_loading_man_data; Task *task_key_word_search; void init_thread(TaskGroup * thread) { task_init_man_data = task_new(thread,0.3,(TaskRunFunc)init_man_data,NULL); task_set_active(task_init_man_data); task_extract_man_data = task_new(thread,0.5,(TaskRunFunc)extract_man_data,NULL); task_set_active(task_extract_man_data); task_add_data_to_clist = task_new(thread,0.7,(TaskRunFunc)add_data_to_clist,NULL); task_set_active(task_add_data_to_clist); task_loading_man_data = task_new(thread,0.31,(TaskRunFunc)loading_man_data,NULL); task_key_word_search = task_new(thread,0.5,(TaskRunFunc)key_word_search_taskfunc,NULL); } gman-0.9.3/taskfunc.h0100644000311700000120000000046207472365646013146 0ustar wxkwheel#ifndef _TASKFUNC_H_ #define _TASKFUNC_H_ #include "task.h" extern Task *task_init_man_data; extern Task *task_extract_man_data; extern Task *task_add_data_to_clist; extern Task *task_loading_man_data; extern Task *task_key_word_search; void init_thread(TaskGroup * thread); int init_man_data(); #endif gman-0.9.3/test.c0100644000311700000120000000016207472365646012277 0ustar wxkwheel#include "kman.h" #include void main() { ManPath a("/usr/man"); printf("size = %d",a.GetSize(1)); } gman-0.9.3/testcontext.c0100644000311700000120000000056607472365646013714 0ustar wxkwheel#include #include "context.h" main() { int i; AppContext context(NULL); context.set_value("test",(void*)1234); context.set_value("v_size",(void*)1024); context.restore_default("test"); context.display_values(); i = (int)context.get_value("v_size"); printf("v_size = %d, h_size = %d, test = %d",i,context.get_value("h_size"),context.get_value("test")); } gman-0.9.3/testdict.c0100644000311700000120000000050607472365646013145 0ustar wxkwheel/*************** testdict.c ******************/ #include "list.h" #include void main() { Dictionary * dict; dict = new Dictionary; dict->add_item("/usr/man",(void *)100); dict->add_item("/usr/local/man",(void * )200); printf("size = %d, /usr/man = %d\n",dict->get_size(),dict->get_value("/usr/local/man")); } gman-0.9.3/testlist.c0100644000311700000120000000041307472365646013172 0ustar wxkwheel#include "list.h" #include void main() { List * a; int i,j,k; a = new List; for (i = 0;i<100;i++) { a->add_item((void *)i); } a->delete_item(15); j = 0; while(!a->meet_end(j)) { k = (int)a->get_item(j++); printf("%d ,j = %d\n",k,j); } } gman-0.9.3/testmem.c0100644000311700000120000000031307472365646012774 0ustar wxkwheel#include #include void main() { int i; void *a,*b; for (i = 1;i<100;i++) { a = malloc(i); b = malloc(1); printf("i = %d, space = %d\n",i,b-a); free(b); free(a); } } gman-0.9.3/testtask.c0100644000311700000120000000165407472365646013171 0ustar wxkwheel#include "task.h" #include #include int task_runb(int state, void * data); int task_runa(int state, void * data); Task *a,*b; void main() { TaskGroup * task_group; task_group = task_group_new(); b = task_new(task_group,0.5,task_runb,"b"); a = task_new(task_group,0.4,task_runa,"a"); task_set_active(b);usleep(15000); //task_set_active(a); //task_set_active(b); sleep(4); } int task_runa(int state, void* data) { static int i; int j,k; if(state&TASK_START) { printf("task a begain... state = %d",state); write(1,"task a begin to run...\n",24); i = 0; //task_set_active(b); } for(j = 0;j < 100 && i< 2000;j++,i++) { write(1,data,1); } usleep(1); return (i<2000); } int task_runb(int state, void* data) { static int i; int j,k; if(state&TASK_START) i = 0; for(j = 0;j < 100 && i< 1000;j++,i++) write(1,data,1); if(i==500) task_set_active(a); write(1,"\n",1); return (i<1000); } gman-0.9.3/util.c0100644000311700000120000001337507472365646012307 0ustar wxkwheel/* * util.c * * Copyright (c) 1990, 1991, John W. Eaton. * * You may distribute under the terms of the GNU General Public * License as specified in the file COPYING that comes with the man * distribution. * * John W. Eaton * jwe@che.utexas.edu * Department of Chemical Engineering * The University of Texas at Austin * Austin, Texas 78712 */ #include #include #include #include #include #include #include #include #include #include #include #include "util.h" #include "gripedefs.h" int debug = 0; char * progname = 0; /* * Extract last element of a name like /foo/bar/baz. */ char * mkprogname (char *s) { char *t; t = strrchr (s, '/'); if (t == (char *)NULL) t = s; else t++; return my_strdup (t); } /* * Is file a nonempty and newer than file b? * * case: * * a newer than b returns 1 * a older than b returns 0 * stat on a fails or a empty returns -1 * stat on b fails or b empty returns -2 * both fail or empty returns -3 */ int is_newer (char *fa, char *fb) { struct stat fa_sb; struct stat fb_sb; register int fa_stat; register int fb_stat; register int status = 0; fa_stat = stat (fa, &fa_sb); if (fa_stat != 0 || fa_sb.st_size == 0) status = 1; fb_stat = stat (fb, &fb_sb); if (fb_stat != 0 || fb_sb.st_size == 0) status |= 2; if (status != 0) return -status; return (fa_sb.st_mtime > fb_sb.st_mtime); } int ruid, rgid, euid, egid, suid; void get_permissions (void) { ruid = getuid(); euid = geteuid(); rgid = getgid(); egid = getegid(); suid = (ruid != euid || rgid != egid); } void no_privileges (void) { if (suid) { #ifndef __CYGWIN32__ setreuid(ruid, ruid); setregid(rgid, rgid); #endif suid = 0; } } /* * Unfortunately, Linux libc system() ignores SIGINT and SIGQUIT * The consequence is that "man -K" cannot be interrupted. * Here a private copy that doesn't fiddle with signals. * (But see below.) */ static int system0 (char *command) { int pid, pid2, status; pid = fork(); if (pid == -1) { perror(progname); fatal (CANNOT_FORK, command); } if (pid == 0) { char *argv[4]; argv[0] = "sh"; argv[1] = "-c"; argv[2] = command; argv[3] = 0; execv("/bin/sh", argv); /* was: execve(*,*,environ); */ exit(127); } do { pid2 = wait(&status); if (pid2 == -1) return -1; } while(pid2 != pid); return status; } /* * What to do upon an interrupt? Experience shows that * if we exit immediately, sh notices that its child has * died and will try to fiddle with the tty. * Simultaneously, also less will fiddle with the tty, * resetting the mode before exiting. * This leads to undesirable races. So, we catch SIGINT here * and exit after the child has exited. */ static int interrupted = 0; static void catch_int(int a) { interrupted = 1; } static int system1 (char *command) { void (*prev_handler)(int) = signal (SIGINT,catch_int); int ret = system0(command); if (interrupted) exit(1); signal(SIGINT,prev_handler); return ret; } static int my_system (char *command) { int pid, pid2, status, stat; if (!suid) return system1 (command); #ifdef _POSIX_SAVED_IDS /* we need not fork */ setuid(ruid); setgid(rgid); status = system1(command); setuid(euid); setgid(egid); return (WIFEXITED(status) ? WEXITSTATUS(status) : 127); #endif fflush(stdout); fflush(stderr); pid = fork(); if (pid == -1) { perror(progname); fatal (CANNOT_FORK, command); } if (pid == 0) { setuid(ruid); setgid(rgid); status = system1 (command); exit(WIFEXITED(status) ? WEXITSTATUS(status) : 127); } pid2 = wait (&stat); if (pid2 == -1) { perror(progname); fatal (WAIT_FAILED, command); /* interrupted? */ } if (pid2 != pid) fatal (GOT_WRONG_PID); if (WIFEXITED(stat) && WEXITSTATUS(stat) != 127) return WEXITSTATUS(stat); fatal (CHILD_TERMINATED_ABNORMALLY, command); return -1; /* not reached */ } FILE * my_popen(const char *command, const char *type) { FILE *r; if (!suid) return popen(command, type); #ifdef _POSIX_SAVED_IDS setuid(ruid); setgid(rgid); r = popen(command, type); setuid(euid); setgid(egid); return r; #endif no_privileges(); return popen(command, type); } /* * Attempt a system () call. */ int do_system_command (char *command, int silent) { int status = 0; /* * If we're debugging, don't really execute the command -- you never * know what might be in that mangled string :-O. */ if (debug == 1) gripe (NO_EXEC, command); else status = my_system (command); if (status && !silent) gripe (SYSTEM_FAILED, command, status); return status; } char * my_malloc (int n) { char *s = (char*) malloc(n); if (!s) fatal (OUT_OF_MEMORY, n); return s; } char * my_strdup (char *s) { char *t = my_malloc(strlen(s) + 1); strcpy(t, s); return t; } /******************* modifyed by Wang XinKai ,1999.3.19 *********/ char *getmsg(int n) { static char buffer[100]; buffer[0] = 0; //sprintf(buffer,"error, errorcode = %d\n",n); return buffer; } void gripe (int n, ...) { va_list p; va_start(p, n); vfprintf (stderr, getmsg(n), p); va_end(p); fflush (stderr); } void fatal (int n, ...) { va_list p; fprintf (stderr, "%s: ", progname); va_start(p, n); vfprintf (stderr, getmsg(n), p); va_end(p); exit (1); } /************************** modify end ************************/ gman-0.9.3/util.h0100644000311700000120000000070707472365646012307 0ustar wxkwheel/* functions and variables exported from util.c */ void get_permissions (void); void no_privileges (void); char *my_malloc (int n); char *my_strdup (char *s); char *mkprogname (char *s); int is_newer (char *fa, char *fb); int do_system_command (char *cmd, int silent); FILE *my_popen(const char *cmd, const char *type); void gripe (int n, ...); void fatal (int n, ...); extern int ruid, rgid, euid, egid, suid; extern char * progname; extern int debug; gman-0.9.3/window2.c0100644000311700000120000002551407472365646012721 0ustar wxkwheel/******************** departed from menu.c ***************/ /******************** window2.c **************************/ #include #include #include "menu.h" #include "list.h" #include "util.h" #include "mandata.h" #include "taskfunc.h" static int window2_button_callback(GtkWidget *w, gpointer data); static int window2_delete_event_callback(GtkWidget *w, GdkEvent *event,gpointer data); static int clist2_select_callback(GtkWidget *w,int row, int column, GdkEvent *event,gpointer data); static void entry2_activate_callback(GtkWidget *,gpointer); static void entry2_changed_callback(GtkWidget *,gpointer); int signal_window2_change; //used by window2_button_callback() to decide whether to take action or not GtkWidget * window2 = NULL; //edit paths window GtkWidget * clist2 = NULL; int clist2_selected_row; GtkWidget* create_window2 () { GtkWidget *window2; GtkWidget *hbox3; GtkWidget *vbox1; GtkWidget *clist2; GtkWidget *swindow; GtkWidget *hbox4; GtkWidget *button1; GtkWidget *button2; GtkWidget *vbox2; GtkWidget *vbox3; GtkWidget *button3; GtkWidget *button4; GtkWidget *button5; GtkWidget *entry2; gchar *titles[3] = { "a", "Path", "Items" }; window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL); // GTK_WIDGET_UNSET_FLAGS (window2, GTK_CAN_FOCUS); gtk_object_set_data (GTK_OBJECT (window2), "window2", window2); gtk_window_set_title (GTK_WINDOW (window2), "edit man paths"); gtk_window_set_policy (GTK_WINDOW (window2), FALSE, TRUE, FALSE); gtk_widget_set_usize(window2,300,220); gtk_signal_connect(GTK_OBJECT(window2), "delete_event", GTK_SIGNAL_FUNC(window2_delete_event_callback), (void*)1); hbox3 = gtk_hbox_new (FALSE, 10); gtk_object_set_data (GTK_OBJECT (window2), "hbox3", hbox3); gtk_widget_show (hbox3); gtk_container_add (GTK_CONTAINER (window2), hbox3); gtk_container_border_width (GTK_CONTAINER (hbox3), 10); vbox1 = gtk_vbox_new (FALSE, 10); gtk_object_set_data (GTK_OBJECT (window2), "vbox1", vbox1); gtk_widget_show (vbox1); gtk_box_pack_start (GTK_BOX (hbox3), vbox1, TRUE, TRUE, 0); vbox3 = gtk_vbox_new (FALSE, 0); gtk_object_set_data (GTK_OBJECT (window2), "vbox3", vbox1); gtk_widget_show (vbox3); gtk_box_pack_start (GTK_BOX (vbox1), vbox3, TRUE, TRUE, 0); clist2 = gtk_clist_new_with_titles( 3, titles); ::clist2 = clist2; swindow = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); //GTK_WIDGET_UNSET_FLAGS (swindow, GTK_CAN_FOCUS); gtk_clist_set_column_width(GTK_CLIST(clist2),0,10); gtk_clist_set_column_width(GTK_CLIST(clist2),1,130); gtk_clist_set_column_justification(GTK_CLIST(clist2),0,GTK_JUSTIFY_CENTER); gtk_clist_set_column_justification(GTK_CLIST(clist2),2,GTK_JUSTIFY_RIGHT); gtk_clist_set_selection_mode(GTK_CLIST(clist2),GTK_SELECTION_SINGLE); gtk_clist_column_titles_passive(GTK_CLIST(clist2)); gtk_container_add (GTK_CONTAINER (swindow), clist2); gtk_signal_connect(GTK_OBJECT(clist2),"select_row",GTK_SIGNAL_FUNC(clist2_select_callback),(void*)1); gtk_signal_connect(GTK_OBJECT(clist2),"unselect_row",GTK_SIGNAL_FUNC(clist2_select_callback),(void*)0); gtk_object_set_data (GTK_OBJECT (window2), "clist2", clist2); gtk_widget_show (clist2); gtk_widget_show (swindow); gtk_box_pack_start (GTK_BOX (vbox3), swindow, TRUE, TRUE, 0); entry2 = gtk_entry_new_with_max_length (200); gtk_object_set_data (GTK_OBJECT (window2), "entry2", entry2); gtk_widget_show (entry2); gtk_box_pack_start (GTK_BOX (vbox3), entry2, FALSE, FALSE, 0); gtk_signal_connect(GTK_OBJECT(entry2),"activate",GTK_SIGNAL_FUNC(entry2_activate_callback),NULL); gtk_signal_connect(GTK_OBJECT(entry2),"changed",GTK_SIGNAL_FUNC(entry2_changed_callback),NULL); gtk_tooltips_set_tip (tooltips, entry2, "Input new path here", NULL); hbox4 = gtk_hbox_new (TRUE, 15); gtk_object_set_data (GTK_OBJECT (window2), "hbox4", hbox4); gtk_widget_show (hbox4); gtk_box_pack_end (GTK_BOX (vbox1), hbox4, FALSE, TRUE, 0); button1 = gtk_button_new_with_label ("OK"); gtk_object_set_data (GTK_OBJECT (window2), "button1", button1); gtk_widget_show (button1); gtk_box_pack_start (GTK_BOX (hbox4), button1, TRUE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button1),"clicked",(GtkSignalFunc)window2_button_callback,(void*)1); GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT); gtk_widget_grab_default (button1); button2 = gtk_button_new_with_label ("apply"); gtk_object_set_data (GTK_OBJECT (window2), "button2", button2); gtk_widget_show (button2); gtk_box_pack_start (GTK_BOX (hbox4), button2, TRUE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button2),"clicked",(GtkSignalFunc)window2_button_callback,(void*)2); vbox2 = gtk_vbox_new (FALSE, 0); gtk_object_set_data (GTK_OBJECT (window2), "vbox2", vbox2); gtk_widget_show (vbox2); gtk_box_pack_start (GTK_BOX (hbox3), vbox2, FALSE, TRUE, 0); button3 = gtk_button_new_with_label ("Add new"); gtk_object_set_data (GTK_OBJECT (window2), "button3", button3); gtk_widget_show (button3); gtk_box_pack_start (GTK_BOX (vbox2), button3, FALSE, FALSE, 15); gtk_signal_connect (GTK_OBJECT(button3),"clicked",(GtkSignalFunc)window2_button_callback,(void*)3); gtk_widget_set_sensitive(button3,0); button4 = gtk_button_new_with_label ("Delete"); gtk_object_set_data (GTK_OBJECT (window2), "button4", button4); gtk_widget_show (button4); gtk_box_pack_start (GTK_BOX (vbox2), button4, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button4),"clicked",(GtkSignalFunc)window2_button_callback,(void*)4); gtk_widget_set_sensitive(button4,0); button5 = gtk_button_new_with_label ("Default"); gtk_object_set_data (GTK_OBJECT (window2), "button5", button5); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (vbox2), button5, FALSE, FALSE, 15); gtk_signal_connect (GTK_OBJECT(button5),"clicked",(GtkSignalFunc)window2_button_callback,(void*)5); button5 = gtk_button_new_with_label ("Reload"); gtk_object_set_data (GTK_OBJECT (window2), "button6", button5); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (vbox2), button5, FALSE, FALSE, 0); gtk_signal_connect (GTK_OBJECT(button5),"clicked",(GtkSignalFunc)window2_button_callback,(void*)6); button5 = gtk_button_new_with_label ("Reload all"); gtk_object_set_data (GTK_OBJECT (window2), "button7", button5); gtk_widget_show (button5); gtk_box_pack_start (GTK_BOX (vbox2), button5, FALSE, FALSE, 15); gtk_signal_connect (GTK_OBJECT(button5),"clicked",(GtkSignalFunc)window2_button_callback,(void*)7); return window2; } /******************* tool functions ***********************/ void load_clist2() { int i,j; ManPath * p; gchar * clist_item[3]; gchar buffer[100]; j = man_paths->get_size(); gtk_clist_clear(GTK_CLIST(clist2)); for (i = 0;iget_value(i); if (p) { if (p->active) clist_item[0] ="o"; else clist_item[0] = ""; clist_item[1] = man_paths->get_name(i); sprintf(buffer,"%d",p->GetSize(-1)); clist_item[2] = buffer; } else { clist_item[0] = "o"; clist_item[1] = man_paths->get_name(i); clist_item[2] = "???"; } gtk_clist_append(GTK_CLIST(clist2),clist_item); } } /******************* interfaces to outside***********************/ int edit_paths_callback(GtkWidget *w, gpointer data) { GtkWidget * apply_button,*delete_button,*focus; if (!window2) { window2 = create_window2(); man_paths_to_be_load = new List; clist2_selected_row = -1; } apply_button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(window2),"button2"); gtk_widget_set_sensitive(apply_button,0); delete_button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(window2),"button4"); gtk_widget_set_sensitive(delete_button,0); signal_window2_change = 0; load_clist2(); gtk_widget_show(window2); focus = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(window2),"button1"); gtk_widget_grab_focus (focus); return 1; } /******************* call backs ***********************/ static int window2_delete_event_callback(GtkWidget *w, GdkEvent * event, gpointer data) { GtkWidget * ok_button; ok_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(w),"button1"); gtk_signal_emit_by_name(GTK_OBJECT(ok_button),"clicked"); return 1; } static int window2_button_callback(GtkWidget *w, gpointer data) { GtkWidget * x, *apply_button,*add_new_button; gchar * c, *c2; int i; int select = (int)data; gchar * clist_item[3]; // printf("point2 data = %d\n",select); apply_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button2"); add_new_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button3"); switch(select) { case 1: gtk_widget_hide(window2); //OK case 2: //Apply if(signal_window2_change) { task_set_active(task_extract_man_data); task_set_active(task_add_data_to_clist); } signal_window2_change = 0; gtk_widget_set_sensitive(apply_button,0); break; case 3: //Add New x = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"entry2"); c = gtk_entry_get_text(GTK_ENTRY(x)); if(!strcmp(c,"")) { g_print("g-man: path name can not be empty\n"); break; } if (man_paths->have_item(c)) break; c2 = my_strdup(c); clist_item[0] = "o"; clist_item[1] = c2; clist_item[2] = "???"; gtk_clist_append(GTK_CLIST(clist2),clist_item); man_paths->add_item(c2,(void*)0); man_paths_to_be_load->add_item(c2); task_set_active(task_loading_man_data); signal_window2_change ++; gtk_widget_set_sensitive(apply_button,1); gtk_editable_select_region (GTK_EDITABLE (x), 0, strlen(c)); break; case 4: //Delete if (clist2_selected_row == -1) break; // printf("remove %d\n",clist2_selected_row); i = clist2_selected_row; delete ((ManPath*)(man_paths->get_value(i))); man_paths->delete_item(i); gtk_clist_remove(GTK_CLIST(clist2),i); signal_window2_change ++; gtk_widget_set_sensitive(apply_button,1); break; default: g_print("g-man: sorry... this function not implementd yet, please wait for the future version\n"); }; return 1; } static int clist2_select_callback(GtkWidget *w,int row, int column, GdkEvent *event,gpointer data) { GtkWidget * delete_button; delete_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button4"); if(data) { clist2_selected_row = row; } else { if (clist2_selected_row == row) clist2_selected_row = -1; } gtk_widget_set_sensitive(delete_button,clist2_selected_row != -1); return 0; } static void entry2_activate_callback(GtkWidget *w,gpointer data) { GtkWidget * add_new_button; add_new_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button3"); // printf("button3 = %x\n",add_new_button); gtk_signal_emit_by_name(GTK_OBJECT(add_new_button),"clicked"); } static void entry2_changed_callback(GtkWidget *w,gpointer data) { GtkWidget * add_new_button; add_new_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button3"); // printf("button3 = %x\n",add_new_button); gtk_widget_set_sensitive(add_new_button,strcmp("",gtk_entry_get_text(GTK_ENTRY(w)))); } gman-0.9.3/window2.h0100644000311700000120000000023007472365646012712 0ustar wxkwheel#ifndef _WINDOW2_H_ #define _WINDOW2_H_ #include int edit_paths_callback(GtkWidget *w, gpointer data); extern GtkWidget * clist2; #endif gman-0.9.3/Makefile0100644000311700000120000000263707472365646012625 0ustar wxkwheel# Gman Makefile # You can adjust the following variables. CXX = g++ CXXFLAGS = -DVERSION=\"0.9.3\" `gtk-config --cflags` -O2 -Wall CC = $(CXX) $(CXXFLAGS) GNOMELIB = #`gnome-config --libs gnomeui` GTKLIB = -L/usr/lib/ `gtk-config --libs` prefix = /usr cgi_bin_prefix = /var/www/cgi-bin # There shouldn't be any need to edit anything below this point. all: gman gman: menu.o mandata.o util.o gman.o list.o context.o task.o taskfunc.o window2.o $(CXX) -lgtk -lgdk -lpthread $(GTKLIB) menu.o mandata.o util.o gman.o list.o context.o task.o taskfunc.o window2.o -o gman gman.o: gman.c menu.h $(CC) -c gman.c menu.o: menu.c mandata.h util.h $(CC) -c menu.c -o menu.o mandata.o: mandata.c mandata.h util.h mandatadef.h $(CC) -c mandata.c -o mandata.o util.o: util.c util.h $(CC) -c util.c -o util.o list.o: list.c list.h $(CC) -c list.c context.o: context.c context.h $(CC) -c context.c task.o: task.c task.h $(CC) -c task.c taskfunc.o: taskfunc.c taskfunc.h $(CC) -c taskfunc.c window2.o: window2.c window2.h $(CC) -c window2.c clean: rm -f *.o *~ gman install: test -d $(prefix)/bin || mkdir -p $(prefix)/bin test -d $(prefix)/man/man1 || mkdir -p $(prefix)/man/man1 test -d $(cgi_bin_prefix)/gman || mkdir -p $(cgi_bin_prefix)/gman install -s -m 755 gman $(prefix)/bin install -s -m 755 gman.pl $(prefix)/bin/gman.cgi install -m 644 gman.1x $(prefix)/man/man1 install -s -m 755 gman.pl $(ci_bin_prefix)/gman gman-0.9.3/ChangeLog0100644000311700000120000000171007472365646012726 0ustar wxkwheelChangeLog for G-man by Xinkai Wang v0.9.2 (31.Mar 2001) - CGI front-end for man2html (gman.pl) added. - Two new "View Mode": LocalBrowse and NetBrowse. v0.9.1 (27.Mar 2001) - bug fix in mandata.h:20 and menu.c:592 when compile with GCC 2.95.3, (reported by Petter Sundlf ) v0.9.0 (26.Mar 2001) - add show_mode selecting ("View" menu item). GhostView support. (suggested by Michael T. Babcock ) - rpm package available. v0.0.8 (10/17/99) - pure GTK+ implement, independent from gnome - gramatical and spelling errors corrected in README - fix in Makefile - gman.1x included - "show_warning" option v0.0.7 (10/12/99) - Second release - Should be bug free - keyword search capability - bug-fix for the "task" libary (which is a user-level thread libary) v0.0.2 (8/9/99) - First public release - Should be bug free - multi-thread implement - index search - Read the file README for usage and features gman-0.9.3/README0100644000311700000120000001046707472365646012045 0ustar wxkwheel General Information =================== This is Gman, a GTK+ front end for man. Gman's home page will be in http://homex.s-one.net.sg/user/xkwang/gman (still under construction) This a little piece of software is mostly developed for the new users of Unix/Linux. When I was a newbie of Linux, I felt I always could not find the man pages that I need. I believed the man pages must be somewhere in the system, but I just could not find the name of it. So I thought, maybe we need new graphical man page system. I don't like xman because it looks ugly and it is difficult to use (I felt). I think gnome-help-browser is too slow and it eats too much memory (about 12M on my system). It does not have index search function, and it can not be operated with keyboard shortcuts. I think an ideal help system must have the index search function (just like the help system on windoze). This will help a newbie to find the information that s/he needs, and sometimes help him/her go around to see what other man pages are there in the system, in his leisure time. Gman is nothing else but a simple front-end for the usual man page system. The most basic job of gman is to build a database for all the man pages and display them (or part of them) on the screen. When user decides to read a man page, gman will launch a xterm window and call the normal man system to display the man page in the window. Gman can launch more than one xterm window at same time. And user can use the index search function to look for the man pages that s/he needs. Installation ============ (possibly editing of Makefile and gman.pl) $ make (change to super user if needed) # make install As default, This will put gman binary in /usr/local/bin, and its manual page in /usr/local/man/man1. cgi script in /home/httpd/cgi-bin/gman. If you don't like the default locations, try to change "prefix" and "cgi_bin_prefix" to other values (in Makefile). And, if your perl is not in /usr/bin/perl, you may need to modify the first line in gman.pl accordingly. Features of this version ======================== It's easy to write a simple software that can work, but the problem is in making it work better. It took me a lot of time to improve it's UI and some other little things, such as: 1. Multi-threading. When you have many manual pages on your system, some of the work (such as update window) will take a lot of time. So I used multi-thread programming, which means that the user can input new commands at any time, without waiting for the previous operation to end. 2. ~/.gman file. Every time gman starts up, it will read some configuration information from $HOME/.gman file. And every time gman exits, it will also write the current configuration information to that same file. ~/.gman file is a simple text file and can be edited using any text editor. To do ===== * autoconf support, especially if GNOME support is included. * use of gettext for easier translation to other languages. * improvment for the parser when reading the ~/.gman file (context.c). * internal method of displaying manual pages, not with xterm. Your comments and suggestions will be the most important for gman development. Patches (bug fixes or code additions) are welcome. Final note ========== I wonder if it is worthy for me to spend more time on it. I believe a user-friendly graphical interface is extremely important for a software system. Sometimes (often) people find it even more important than the contents of the software! (windoze is a good example) I hope more people can benefit because of my work. /* gman * Copyright (C) 1999 Xinkai Wang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ gman-0.9.3/gman.1x0100644000311700000120000000444207472444714012347 0ustar wxkwheel.TH GMAN 1x "May 2002" "Gman" .SH NAME gman \- GTK+ based front-end for man, a good replacment for xman. .SH SYNOPSIS .B gman .SH DESCRIPTION .B Gman is a front-end for the original .I man page system. The most basic job of gman is to build a database for all the man pages and display them (or part of them) as a list. When user decides to read a specific man page, .B gman will launch a .I xterm window and call the traditional man system to display the man page in the window. .sp .B Gman can launch more than one window at same time. And user can use the index/key word search function to look for the man pages that he needs. .sp It is simple, but it is useful. .SH OPTIONS There are no command line options for gman, for now. .sp Tips: Currently gman have 4 different modes to present the man pages to you. In the first mode "Xterm", you can add the following line in your ~/.gman file to select the xterm software which you would like to use. .sp xterm_command = rxvt .sp Tips: If GhostView package (command "gv") is aviable on your system. You may set "View"->"GhostView" and gman will present man pages with a ghostview window for you to view and print the man page. .sp Tips: If you have netscape on your system, you may set "View"->"LocalBrowse" and gman will launch a netscape window to show you the man page. .sp Tips: If you have netscape and apache server running ( defult cgi-bin directory is "/var/www/cgi-bin") , you may enjoy the full NetBrowse mode by set "View"->"NetBrowse". In this mode, you can view the pages with netscape browser and navigate from one man page to another (by click the links in the man pages). This mode is very useful. .SH FILES .TP .I ~/.gman Contains configuration information for gman, such as window size and paths where the manual pages are contained. For example, .sp v_size = 400 .br h_size = 300 .br xterm_command = rxvt .br show_warning = 0 .br man_paths = /usr/man:/usr/local/man:/usr/X11R6/man .sp For more information, see init_context() function in gman.c for all the options avialiable. .sp ~/.gman is read by gman on startup, and written on exit. .SH SEE ALSO .BR man (1), .BR man (7), .BR xterm (1). .SH AUTHOR .B Gman was written by a smart gay named Xinkai Wang . Home page of gman is at: .br .I http://homex.coolconnect.com/user/xkwang/gman/ gman-0.9.3/AUTHORS0100644000311700000120000000024607472365646012227 0ustar wxkwheel Gman main author: Xinkai Wang Special thanks to Josip Rodin , who provided a patch to improve gman from 0.0.7 to 0.0.8. gman-0.9.3/README.orig0100644000311700000120000001015107472365646012772 0ustar wxkwheel General Information =================== This is Gman, a GTK+ front end for man. Gman's home page will be in http://homex.s-one.net.sg/user/xkwang/gman (still under construction) This a little piece of software is mostly developed for the new users of Unix/Linux. When I was a newbie of Linux, I felt I always could not find the man pages that I need. I believed the man pages must be somewhere in the system, but I just could not find the name of it. So I thought, maybe we need new graphical man page system. I don't like xman because it looks ugly and it is difficult to use (I felt). I think gnome-help-browser is too slow and it eats too much memory (about 12M on my system). It does not have index search function, and it can not be operated with keyboard shortcuts. I think an ideal help system must have the index search function (just like the help system on windoze). This will help a newbie to find the information that s/he needs, and sometimes help him/her go around to see what other man pages are there in the system, in his leisure time. Gman is nothing else but a simple front-end for the usual man page system. The most basic job of gman is to build a database for all the man pages and display them (or part of them) on the screen. When user decides to read a man page, gman will launch a xterm window and call the normal man system to display the man page in the window. Gman can launch more than one xterm window at same time. And user can use the index search function to look for the man pages that s/he needs. Installation ============ (possibly editing of Makefile) $ make (change to super user if needed) # make install This will put gman binary in /usr/local/bin, and its manual page in /usr/local/man/man1. Features of this version ======================== It's easy to write a simple software that can work, but the problem is in making it work better. It took me a lot of time to improve it's UI and some other little things, such as: 1. Multi-threading. When you have many manual pages on your system, some of the work (such as update window) will take a lot of time. So I used multi-thread programming, which means that the user can input new commands at any time, without waiting for the previous operation to end. 2. ~/.gman file. Every time gman starts up, it will read some configuration information from $HOME/.gman file. And every time gman exits, it will also write the current configuration information to that same file. ~/.gman file is a simple text file and can be edited using any text editor. To do ===== * autoconf support, especially if GNOME support is included. * use of gettext for easier translation to other languages. * improvment for the parser when reading the ~/.gman file (context.c). * internal method of displaying manual pages, not with xterm. Your comments and suggestions will be the most important for gman development. Patches (bug fixes or code additions) are welcome. Final note ========== I wonder if it is worthy for me to spend more time on it. Maybe, if you are already an expert, you will feel I'm wasting my time doing such useless work. I believe a user-friendly graphical interface is extremely important for a software system. Sometimes (often) people find it even more important than the contents of the software! (windoze is a good example) I hope you will benefit from my work. /* gman * Copyright (C) 1999 Xinkai Wang * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ gman-0.9.3/README.rej0100644000311700000120000001135407472365646012620 0ustar wxkwheel*************** *** 11,28 **** Unix/Linux. When I was a newbie of Linux, I felt I always could not find the man pages that I need. I believed the man pages must be somewhere in the system, but I just could not find the name of it. - So I thought, maybe we need new graphical man page system. I don't like xman because it looks ugly and it is difficult to use (I felt). I think gnome-help-browser is too slow and it eats too much memory (about 12M on my system). It does not have index search function, and it can not be operated with keyboard shortcuts. - I think an ideal help system must have the index search function (just like the help system on windoze). This will help a newbie to find the information that s/he needs, and sometimes help him/her go around to see what other man pages are there in the system, in his leisure time. - Gman is nothing else but a simple front-end for the usual man page system. The most basic job of gman is to build a database for all the man pages and display them (or part of them) on the screen. When user decides to read --- 11,28 ---- Unix/Linux. When I was a newbie of Linux, I felt I always could not find the man pages that I need. I believed the man pages must be somewhere in the system, but I just could not find the name of it. + So I thought, maybe we need new graphical man page system. I don't like xman because it looks ugly and it is difficult to use (I felt). I think gnome-help-browser is too slow and it eats too much memory (about 12M on my system). It does not have index search function, and it can not be operated with keyboard shortcuts. + I think an ideal help system must have the index search function (just like the help system on windoze). This will help a newbie to find the information that s/he needs, and sometimes help him/her go around to see what other man pages are there in the system, in his leisure time. + Gman is nothing else but a simple front-end for the usual man page system. The most basic job of gman is to build a database for all the man pages and display them (or part of them) on the screen. When user decides to read *************** *** 38,44 **** $ make (change to super user if needed) # make install - This will put gman binary in /usr/local/bin, and its manual page in /usr/local/man/man1. --- 38,44 ---- $ make (change to super user if needed) # make install + This will put gman binary in /usr/local/bin, and its manual page in /usr/local/man/man1. *************** *** 48,60 **** It's easy to write a simple software that can work, but the problem is in making it work better. It took me a lot of time to improve it's UI and some other little things, such as: - 1. Multi-threading. When you have many manual pages on your system, some of the work (such as update window) will take a lot of time. So I used multi-thread programming, which means that the user can input new commands at any time, without waiting for the previous operation to end. - 2. ~/.gman file. Every time gman starts up, it will read some configuration information from $HOME/.gman file. And every time gman exits, it will also write the --- 48,60 ---- It's easy to write a simple software that can work, but the problem is in making it work better. It took me a lot of time to improve it's UI and some other little things, such as: + 1. Multi-threading. When you have many manual pages on your system, some of the work (such as update window) will take a lot of time. So I used multi-thread programming, which means that the user can input new commands at any time, without waiting for the previous operation to end. + 2. ~/.gman file. Every time gman starts up, it will read some configuration information from $HOME/.gman file. And every time gman exits, it will also write the *************** *** 64,74 **** To do ===== - * autoconf support, especially if GNOME support is included. * use of gettext for easier translation to other languages. - * improvment for the parser when reading the ~/.gman file (context.c). * internal method of displaying manual pages, not with xterm. - Your comments and suggestions will be the most important for gman development. Patches (bug fixes or code additions) are welcome. --- 64,74 ---- To do ===== * use of gettext for easier translation to other languages. + * autoconf support, especially if GNOME support is included. + * improvement for the parser which reads the ~/.gman file (context.c). * internal method of displaying manual pages, not with xterm. + Your comments and suggestions will be the most important for gman development. Patches (bug fixes or code additions) are welcome. gman-0.9.3/gman.pl0100755000311700000120000000262507472365647012445 0ustar wxkwheel#!/usr/bin/perl use strict(all); my $cgi_path = "/cgi-bin/gman/gman.pl"; my $man2html = "man2html -M $cgi_path"; my $path = `man -w @ARGV`; my $tmp_file = "/tmp/gman.$ARGV[1].$ARGV[0]"; if (!&file_exist($path)) { my $name = lc($ARGV[1]); $path = `man -w $ARGV[0] $name`; # print "check point 0.9\n"; } if (!&file_exist($path)) { print < 404 Not Found

Not Found

The requested man page $ARGV[1]($ARGV[0]) was not found on this server.

end_of_line die; } my $page; if ($path =~ /gz$/) { my $file = `gzip -cd $path`; open (TEMPFILE,">$tmp_file"); print TEMPFILE $file; close (TEMPFILE); $page = `$man2html $tmp_file`; `rm $tmp_file`; } else { $page = `$man2html $path`; } $page =~ s/This document was created by\s*man2html<\/A>,\s*using the manual pages.
/This document was created by
man2html<\/A> for gman<\/A>, using the manual pages.
/; print $page; #print `cat /home/wxk/src/gtk/gman.html`; sub file_exist { open (FILE,$_[0]); my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat(FILE); close(FILE); # print "check point 0.5, size = $size, $_[0]\n"; if ($size == 0 or $size eq null) { return 0; } else { return 1; } } gman-0.9.3/cgi.pl0100755000311700000120000000021607472365647012257 0ustar wxkwheel#!/usr/local/bin/perl open (LOG,">>/dat/gman.log"); while(<>) { print STDERR "$_"; } print `cat /home/wxk/src/gtk/gman.html`; close(LOG); gman-0.9.3/.gman-0.9.0-1.spec.swp0100600000311700000120000003000007472365647014423 0ustar wxkwheelb0VIM 5.6 :C8wxkubiqd26~wxk/src/gtk/gman-0.9.0/gman-0.9.0-1.specU3210#"! Utp2ad 2u-%z k j d Z A @ 9   v : 9 2    q 9 8  W [ Some changelog entries trimmed for brevity. -Editor.[ Some changelog entries trimmed for brevity. -Editor. ]- I[ Some changelog entries trimmed for brevity. -Editor. ]- [ Some changelog entries trimmed for brevity. -Editor. ][ Some changelog entries trimm[ Some changelog entries trimmed for brevity. -Editor. ][ Some ch[ Some [ Some changelog entries trimmed for brevity. -Editor. ]- Injected new description and group.* Wed Feb 24 1999 Preston Brown - auto rebuild in the new build environment (release 3)* Sun Mar 21 1999 Cristian Gafton %changelog/usr/man/man1/eject.1/usr/bin/eject%doc README TODO COPYING ChangeLog%defattr(-,root,root)%filesrm -rf $RPM_BUILD_ROOT%cleaninstall -m 644 eject.1 $RPM_BUILD_ROOT/usr/man/man1/eject.1install -s -m 755 eject $RPM_BUILD_ROOT/usr/bin/ejectmkdir -p $RPM_BUILD_ROOT/usr/man/man1mkdir -p $RPM_BUILD_ROOT/usr/binrm -rf $RPM_BUILD_ROOT%installmake RPM_OPT_FLAGS="$RPM_OPT_FLAGS"%build%patch -p1 -b .buildroot%setup -q%prepIt is simple but useful, especialy for Linux newbies.launch a xterm window and call the traditional man system to display the man page in the window.man pages and display them (or part of them) as a list. When user decides to read a specific man page, gman willGman is a front-end for the original man page system. The most basic job of gman is to build a database for all the%descriptionBuildRoot: /var/tmp/%{name}-buildrootPatch: Source: http://homex.coolconnect.com/user/xkwang/gman/gman-0.9.0.tar.gzGroup: Applications/SystemCopyright: GPLRelease: 1Version: 0.9.0Name: gmanSummary: Gtk+ front-end for man, a good replacment for xmangman-0.9.3/COPYING0100644000311700000120000004307607472365647012223 0ustar wxkwheel GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gman-0.9.3/gman-0.9.3-1.spec0100644000311700000120000000276207472370220013545 0ustar wxkwheelSummary: Gtk+ front-end for man, a good replacment for xman Name: gman Version: 0.9.3 Release: 1 Copyright: GPL Group: Applications/System Source: http://homex.coolconnect.com/user/xkwang/gman/gman-0.9.3.tar.gz BuildRoot: /var/tmp/%{name}-buildroot %description Gman is a front-end for the original man page system. The most basic job of gman is to build a database for all the man pages and display them (or part of them) as a list. When user click on a item in the list, gman will launch a new window (xterm, cxterm, gv, netscape browser, etc.) and call the traditional man system to display the man page to the user. It is simple but useful, especialy for the Linux newbies who have difficalty in finding information with traditional man system. %prep %setup -q %build make %install rm -rf $RPM_BUILD_ROOT mkdir -p $RPM_BUILD_ROOT/usr/bin mkdir -p $RPM_BUILD_ROOT/usr/man/man1 mkdir -p $RPM_BUILD_ROOT/var/www/cgi-bin/gman install -s -m 755 gman $RPM_BUILD_ROOT/usr/bin/gman install -m 755 gman.pl $RPM_BUILD_ROOT/usr/bin/gman.cgi install -m 644 gman.1x $RPM_BUILD_ROOT/usr/man/man1/gman.1x install -m 755 gman.pl $RPM_BUILD_ROOT/var/www/cgi-bin/gman/gman.pl %clean #rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root) %doc README ChangeLog AUTHORS COPYING /usr/bin/gman /usr/man/man1/gman.1x.gz /usr/bin/gman.cgi /var/www/cgi-bin/gman/gman.pl %changelog * Sun May 18 2002 Wang Xinkai - minor update for RedHat 7.x * Mon Mar 26 2001 Wang Xinkai - first build