Codebase list gman / 57d5597
Import Upstream version 0.0.8 Boyuan Yang 4 years ago
35 changed file(s) with 4228 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 gman:
1 Xinkai Wang <aakwxk@hotmail.com>
2
3 special thanks to Josip Rodin<jrodin@jagor.srce.hr>,
4 who provide a patch to improve gman from 0.0.7 to 0.0.8
5
0 ChangeLog for G-man by Xinkai Wang
1
2 v0.0.8 (10/17/99)
3 - pure GTK+ implement, independent from gnome
4 - gramatical and spelling errors corrected in README
5 - fix in Makefile
6 - gman.1x included
7 - "show_warning" option
8
9 v0.0.7 (10/12/99)
10 - Second release
11 - Should be bug free
12 - keyword search capability
13 - bug-fix for the "task" libary (which is a user-level thread libary)
14
15 v0.0.2 (8/9/99)
16 - First public release
17 - Should be bug free
18 - multi-thread implement
19 - index search
20 - Read the file README for usage and features
0 # Gman Makefile
1 # You can adjust the following variables.
2 CXX = g++
3 CXXFLAGS = -DVERSION=\"0.0.8\" `gtk-config --cflags` -O2 #-Wall
4 CC = $(CXX) $(CXXFLAGS)
5
6 GNOMELIB = #`gnome-config --libs gnomeui`
7 prefix = /usr/local
8
9 # There shouldn't be any need to edit anything below this point.
10 all: gman
11
12 gman: menu.o mandata.o util.o gman.o list.o context.o task.o taskfunc.o window2.o
13 $(CC) -lgtk -lgdk -lpthread $(GNOMELIB) menu.o mandata.o util.o gman.o list.o context.o task.o taskfunc.o window2.o -o gman
14
15 gman.o: gman.c menu.h
16 $(CC) -c gman.c
17
18 menu.o: menu.c mandata.h util.h
19 $(CC) -c menu.c -o menu.o
20
21 mandata.o: mandata.c mandata.h util.h mandatadef.h
22 $(CC) -c mandata.c -o mandata.o
23
24 util.o: util.c util.h
25 $(CC) -c util.c -o util.o
26
27 list.o: list.c list.h
28 $(CC) -c list.c
29
30 context.o: context.c context.h
31 $(CC) -c context.c
32
33 task.o: task.c task.h
34 $(CC) -c task.c
35
36 taskfunc.o: taskfunc.c taskfunc.h
37 $(CC) -c taskfunc.c
38
39 window2.o: window2.c window2.h
40 $(CC) -c window2.c
41
42 clean:
43 rm -f *.o gman
44
45 install:
46 test -d $(prefix)/bin || mkdir -p $(prefix)/bin
47 test -d $(prefix)/man/man1 || mkdir -p $(prefix)/man/man1
48 install -s -m 755 gman $(prefix)/bin
49 install -m 644 gman.1x $(prefix)/man/man1
0
1 General Information
2 ===================
3
4 This is Gman, a GTK+ front end for man.
5
6 Gman's home page will be in http://homex.s-one.net.sg/user/xkwang/gman
7 (still under construction)
8
9 This a little piece of software is mostly developed for the new users of
10 Unix/Linux. When I was a newbie of Linux, I felt I always could not find
11 the man pages that I need. I believed the man pages must be somewhere in the
12 system, but I just could not find the name of it.
13
14 So I thought, maybe we need new graphical man page system. I don't like
15 xman because it looks ugly and it is difficult to use (I felt). I think
16 gnome-help-browser is too slow and it eats too much memory (about 12M on my
17 system). It does not have index search function, and it can not be operated
18 with keyboard shortcuts.
19
20 I think an ideal help system must have the index search function (just like
21 the help system on windoze). This will help a newbie to find the
22 information that s/he needs, and sometimes help him/her go around to see
23 what other man pages are there in the system, in his leisure time.
24
25 Gman is nothing else but a simple front-end for the usual man page system.
26 The most basic job of gman is to build a database for all the man pages
27 and display them (or part of them) on the screen. When user decides to read
28 a man page, gman will launch a xterm window and call the normal man system
29 to display the man page in the window. Gman can launch more than one xterm
30 window at same time. And user can use the index search function to look for
31 the man pages that s/he needs.
32
33 Installation
34 ============
35
36 (possibly editing of Makefile)
37 $ make
38 (change to super user if needed)
39 # make install
40
41 This will put gman binary in /usr/local/bin, and its manual page
42 in /usr/local/man/man1.
43
44 Features of this version
45 ========================
46
47 It's easy to write a simple software that can work, but the problem is
48 in making it work better. It took me a lot of time to improve it's UI
49 and some other little things, such as:
50
51 1. Multi-threading.
52 When you have many manual pages on your system, some of the work (such
53 as update window) will take a lot of time. So I used multi-thread
54 programming, which means that the user can input new commands at any
55 time, without waiting for the previous operation to end.
56
57 2. ~/.gman file.
58 Every time gman starts up, it will read some configuration information
59 from $HOME/.gman file. And every time gman exits, it will also write the
60 current configuration information to that same file. ~/.gman file is a
61 simple text file and can be edited using any text editor.
62
63 To do
64 =====
65
66 * autoconf support, especially if GNOME support is included.
67 * use of gettext for easier translation to other languages.
68 * improvment for the parser when reading the ~/.gman file (context.c).
69 * internal method of displaying manual pages, not with xterm.
70
71 Your comments and suggestions will be the most important for gman
72 development. Patches (bug fixes or code additions) are welcome.
73
74 Final note
75 ==========
76
77 I wonder if it is worthy for me to spend more time on it. Maybe, if you are
78 already an expert, you will feel I'm wasting my time doing such useless
79 work. I believe a user-friendly graphical interface is extremely important
80 for a software system. Sometimes (often) people find it even more important
81 than the contents of the software! (windoze is a good example)
82
83 I hope you will benefit from my work.
84
85 /* gman
86 * Copyright (C) 1999 Xinkai Wang
87 *
88 * This program is free software; you can redistribute it and/or modify
89 * it under the terms of the GNU General Public License as published by
90 * the Free Software Foundation; either version 2 of the License, or
91 * (at your option) any later version.
92 *
93 * This program is distributed in the hope that it will be useful,
94 * but WITHOUT ANY WARRANTY; without even the implied warranty of
95 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
96 * GNU General Public License for more details.
97 *
98 * You should have received a copy of the GNU General Public License
99 * along with this program; if not, write to the Free Software
100 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
101 */
0 /* config.h. Generated automatically by configure. */
1 /* config.h.in. Generated automatically from configure.in by autoheader. */
2
3 /* Define if you have the ANSI C header files. */
4 #define STDC_HEADERS 1
5
6 /* Name of package */
7 #define PACKAGE "project1"
8
9 /* Version number of package */
10 #define VERSION "0.1"
11
0 /****************** context.c ******************/
1 /****************** 1999.6.17 ******************/
2 #include <stdio.h>
3 #include <string.h>
4 #include "context.h"
5 #include "util.h"
6
7 AppContext::AppContext()
8 {
9 names = new List();
10 types = new List();
11 values = new List();
12 name_default = new List();
13 type_default = new List();
14 value_default = new List();
15
16 set_default_value("h_size","int",(void *)300);
17 set_default_value("v_size","int",(void *)200);
18 }
19
20 AppContext::~AppContext()
21 {
22 delete names;
23 delete types;
24 delete values;
25 delete name_default;
26 delete type_default;
27 delete value_default;
28 }
29
30 int AppContext::search_name(List * list,char * name)
31 {
32 int i,j;
33 j = list->get_size();
34 for (i = 0;i < j;i++)
35 if (!strcmp((char*)(list->get_item(i)),name)) break;
36 return (i<j)? i:-1;
37 }
38
39 int AppContext::set_value(char * _name, char * type, void * data)
40 {
41 int i;
42 if((i = search_name(name_default,_name)) != -1) {
43 if( !strcmp((char*)type_default->get_item(i),type)) {
44 if((i = search_name(names,_name)) != -1)
45 values->reset_item(i,data);
46 else{
47 values->add_item(data);
48 types->add_item(type);
49 names->add_item(_name);
50 }
51 }
52 else {
53 fprintf(stderr,"Warning: class AppContext: data type mismatch, "
54 " variable \"%s\" is a \"%s\" instead of \"%s\"\n",
55 name_default->get_item(i),type_default->get_item(i),type);
56 return 1;
57 }
58 }
59 else {
60 if((i = search_name(names,_name)) != -1)
61 values->reset_item(i,data);
62 else{
63 values->add_item(data);
64 types->add_item(type);
65 names->add_item(_name);
66 }
67 }
68 return 0;
69 }
70
71 void * AppContext::get_value(char * _name)
72 {
73 int i;
74 if((i = search_name(names,_name)) != -1)
75 return values->get_item(i);
76 else if ((i = search_name(name_default,_name)) != -1)
77 return value_default->get_item(i);
78 return 0;
79 }
80
81 char * AppContext::get_value_type(char * _name)
82 {
83 int i;
84 if((i = search_name(names,_name)) != -1)
85 return (char*)types->get_item(i);
86 else if ((i = search_name(name_default,_name)) != -1)
87 return (char*)type_default->get_item(i);
88 return NULL;
89 }
90
91 void AppContext::set_default_value(char * _name, char * type, void * data)
92 {
93 int i;
94 if((i = search_name(name_default,_name)) != -1) {
95 value_default->reset_item(i,data);
96 type_default->reset_item(i,type);
97 }
98 else{
99 name_default->add_item(_name);
100 type_default->add_item(type);
101 value_default->add_item(data);
102 }
103 }
104
105 void AppContext::restore_default(char * _name)
106 {
107 int i;
108 if((i = search_name(names,_name)) != -1) {
109 values->delete_item(i);
110 types->delete_item(i);
111 names->delete_item(i);
112 }
113 }
114
115 void AppContext::restore_all()
116 {
117 names->delete_all();
118 types->delete_all();
119 values->delete_all();
120 }
121
122 void AppContext::display_values()
123 {
124 int i,j,k;
125 printf("values:\n");
126 j = names->get_size();
127 for(i = 0; i<j;i++)
128 if(!strcmp((char*)types->get_item(i),"char*"))
129 printf("\"%s\" = \"%s\"\n",names->get_item(i),values->get_item(i));
130 else if(!strcmp((char*)types->get_item(i),"int"))
131 printf("\"%s\" = %d\n",names->get_item(i),values->get_item(i));
132 else
133 printf("\"%s\" = 0x%x\n",names->get_item(i),values->get_item(i));
134 printf("default values:\n");
135 j = name_default->get_size();
136 for(i = 0; i<j;i++)
137 if(!strcmp((char*)type_default->get_item(i),"char*"))
138 printf("\"%s\" = \"%s\"\n",name_default->get_item(i),value_default->get_item(i));
139 else if(!strcmp((char*)type_default->get_item(i),"int"))
140 printf("\"%s\" = %d\n",name_default->get_item(i),value_default->get_item(i));
141 else
142 printf("\"%s\" = 0x%x\n",name_default->get_item(i),value_default->get_item(i));
143 }
144
145 #define BUFFER_LENGTH 200
146 #define BEGIN 1
147 #define NAME 2
148 #define NAME_ESCAPE 4
149 #define VALUE 3
150
151 static int is_blank(char c) { return c==' ' || c==9;}
152 static int is_end(char c) { return c=='\n' || c == 0;}
153 static int is_number(char c) {return c<='9' && c>='0';}
154
155 static void * my_parser(char *a, char ** type)
156 {
157 char * b;
158 int n;
159 for(b = a; is_number(*b) && !is_blank(*b) && !is_end(*b);b++);
160 if(!(is_blank(*b)||is_end(*b))) {
161 for(;!is_blank(*b) && !is_end(*b);b++);
162 *b = '\0';
163 *type = "char*";
164 return (void*)my_strdup(a);
165 }
166 else {
167 *type = "int";
168 sscanf(a,"%d",&n);
169 return (void*) n;
170 }
171 }
172
173 void AppContext::load(FILE * fd)
174 {
175 int i,j,k,state;
176 long pos;
177 char *a,*b,*c,*name,*type;
178 void * value;
179 char buffer[BUFFER_LENGTH];
180
181 a = buffer;
182 pos = 0L;
183 for(k = 1;k;){
184 fseek(fd,pos,SEEK_SET);
185 i = fread(buffer,1,BUFFER_LENGTH-1,fd);
186 if (i == 0) break;
187 buffer[i] = '\0';
188 //printf(buffer);
189 b = strchr(buffer,(int)'\n');
190 if (b) {
191 pos += b - buffer +1;
192 *b = '\0';
193 }
194 else k = 0;
195
196 for(a = buffer;is_blank(*a) && !is_end(*a);a++);
197 if (*a == '#' || is_end(*a)) continue;
198 for(b = a;!is_blank(*b) && !is_end(*b) && *b != '=';b++);
199 if(is_end(*b)) continue;
200 c = strchr(b,(int)'=');
201 if(!c) continue;
202 c++;
203 for(;is_blank(*c) && !is_end(*c);c++);
204 if(is_end(*c)) continue;
205 *b = 0;
206 // printf("name = %s, value = %s",a,c);
207 name = my_strdup(a);
208 value = my_parser(c,&type);
209 set_value(name,type,value);
210 }
211 }
212
213 void AppContext::save(FILE * fp, char * header)
214 {
215 int i,j,k;
216 char * type;
217 if(header != NULL)
218 fprintf(fp,"#%s\n\n",header);
219
220 j = names->get_size();
221 for (i = 0;i<j;i++) {
222 type = (char*)types->get_item(i);
223 if (!strcmp(type,"char*"))
224 fprintf(fp,"%s = %s\n",names->get_item(i),values->get_item(i));
225 else if (!strcmp(type,"int"))
226 fprintf(fp,"%s = %d\n",names->get_item(i),values->get_item(i));
227 else fprintf(stderr,"class AppContext: save: type \"%s\" does not be supported yet.\n",type);
228 }
229 }
230
231 #undef BUFFER_LENGTH
232
233
0 /******************** context.h ********************/
1
2 #ifndef _CONTEXT_H
3 #define _CONTEXT_H
4
5 #include <stdio.h>
6 #include "list.h"
7
8 class AppContext
9 {
10 public:
11 AppContext();
12 ~AppContext();
13 void * get_value(char * name);
14 char * get_value_type(char * name);
15 int set_value(char * name, char * type, void * buffer);
16 void set_default_value(char *name, char * type, void * buffer);
17 /* AppContext::set_value() and set_default_value() only implement simpliest
18 data management function. If the name or type is in a temp buffer,
19 it is caller's duty to do strdup() before call the set_value() or
20 set_default_value() */
21 void restore_default(char * name);
22 void restore_all();
23 void load(FILE *);
24 void save(FILE *, char *);
25 void display_values();
26 private:
27 int search_name(List*, char *);
28 List * names;
29 List * types;
30 List * values;
31 List * name_default;
32 List * type_default;
33 List * value_default;
34 };
35
36 #endif
0 .TH GMAN 1x "October 1999" "Gman"
1 .SH NAME
2 gman \- small X/GTK+ based man front-end
3 .SH SYNOPSIS
4 .B gman
5 .SH DESCRIPTION
6 .B Gman
7 is nothing else but only a simple front-end for the original
8 .I man
9 page system. The most basic job of gman is to build a database for all
10 the man pages and display them (or part of them) on the screen. When
11 user decides to read a man page,
12 .B gman
13 will launch a
14 .I xterm
15 window and call the normal man system to display the man page in the
16 window.
17 .sp
18 .B Gman
19 can launch more than one xterm window at same time. And user can use
20 the index search function to look for the man pages that he needs.
21 .sp
22 It is simple, but it is useful.
23 .SH OPTIONS
24 There are no command line options for gman, for now.
25 .SH FILES
26 .PD 0
27 .TP 20
28 .I ~/.gman
29 .PD
30 .SH SEE ALSO
31 .BR man (1),
32 .BR man (7),
33 .BR xterm (1).
34 .SH AUTHOR
35 .B Gman
36 was written by Xinkai Wang <aakwxk@hotmail.com>. Home page of gman is at:
37 .br
38 .I http://homex.s-one.net.sg/user/xkwang/gman
0 /********************* gman.c ********************************/
1 /* gman
2 * Copyright (C) 1999 Xinkai Wang
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <gtk/gtk.h>
23 #include "menu.h"
24 #include "context.h"
25 #include "gman.h"
26 #include "task.h"
27 #include "taskfunc.h"
28 #include "mandata.h"
29 #include <unistd.h>
30
31 void init_context();
32 pthread_mutex_t gtk_lock;
33 pthread_mutex_t context_lock;
34 pthread_mutex_t loading_man_path_lock;
35 AppContext * context;
36 int debuging;
37
38 /********************** main **********************/
39 TaskGroup * task_group;
40
41 void main(int argc, char *argv[])
42 {
43 GtkWidget *window;
44 pthread_t th_init_data;
45
46 pthread_mutex_init(&gtk_lock,NULL);
47 pthread_mutex_init(&context_lock,NULL);
48 pthread_mutex_init(&loading_man_path_lock,NULL);
49 init_context();
50 debuging = (int)context->get_value("debuging");
51 pthread_mutex_lock(&gtk_lock);
52 gtk_init (&argc, &argv);
53 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
54
55 task_group = task_group_new();
56 init_thread(task_group);
57
58 init_main_window(window);
59 gtk_widget_show(window);
60 pthread_mutex_unlock(&gtk_lock);
61 //pthread_create(&th_init_data, NULL, (void * (*)(void*))init_man_data, 0);
62
63 //gtk_main();
64
65 while(1){
66 pthread_mutex_lock(&gtk_lock);
67 while(gtk_events_pending()) {
68 gtk_main_iteration();
69 }
70 pthread_mutex_unlock(&gtk_lock);
71 usleep(10000);
72 }
73
74 return(0);
75 }
76
77 /******************* init_context() *****************/
78 void init_context()
79 {
80 FILE * fd;
81 char buffer[256];
82 context = new AppContext();
83 // context->set_default_value("v_size",(void*)400);
84 context->set_default_value("debuging","int",(void*)0);
85 context->set_default_value("man_paths","char*",(void*)"/usr/man:/usr/local/man:/usr/X11R6/man");
86 context->set_default_value("display_section_policy","int",(void*)0);
87 context->set_default_value("display_section","int",(void*)3);
88 context->set_default_value("xterm_command","char*",(void*)"xterm");
89 context->set_default_value("searching_mode","int",(void*)0);
90 context->set_default_value("show_status_bar","int",(void*)0);
91 context->set_default_value("show_warning","int",(void*)1);
92
93 attach(buffer,getenv("HOME"),".gman");
94 if((fd = fopen(buffer,"r"))) {
95 context->load(fd);
96 fclose(fd);
97 }
98 if(context->get_value("debuging")) context->display_values();
99 //context->save(stdout,"this is just a test");
100 }
101
102
103
0 /******************** context.h ********************/
1
2 #ifndef _GMAN_H
3 #define _GMAN_H
4
5 #include "context.h"
6 #include <pthread.h>
7
8 extern pthread_mutex_t gtk_lock;
9 extern pthread_mutex_t context_lock;
10 extern pthread_mutex_t loading_man_path_lock;
11 extern AppContext * context;
12 extern int debuging;
13 #endif
0 #define CANNOT_FORK 1
1 #define WAIT_FAILED 2
2 #define GOT_WRONG_PID 3
3 #define CHILD_TERMINATED_ABNORMALLY 4
4 #define NO_EXEC 5
5 #define SYSTEM_FAILED 6
6 #define OUT_OF_MEMORY 7
Binary diff not shown
0 /********************* list.c **********************/
1 /********************* 1999.6.13 *******************/
2
3 #include "list.h"
4 #include <stdlib.h>
5 #include <unistd.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <glib.h>
9
10 #define LIST_INIT_SIZE 15
11 List::List()
12 {
13 items = NULL;
14 buffer_length = 0;
15 count = 0;
16 };
17
18 List::~List()
19 {
20 if(items) free(items);
21 };
22
23 void List::add_item(void * item)
24 {
25 if(!items) {
26 items = (void **)malloc((size_t)sizeof(void*)*LIST_INIT_SIZE);
27 if(!items) {
28 perror("class List: can not malloc mem when init:");
29 exit(1);
30 }
31 buffer_length = LIST_INIT_SIZE;
32 }
33 else if(buffer_length == count){
34 items = (void **)realloc((void*)items,sizeof(void *)*(buffer_length+=buffer_length));
35 if(!items){
36 perror("class List: mem not enought when realloc:");
37 exit(1);
38 }
39 }
40 items[count++] = item;
41 }
42
43 void * List::get_item(int handle)
44 {
45 if(handle >= count || handle < 0) return NULL;
46 return items[handle];
47 }
48
49 int List::reset_item(int handle, void * data)
50 {
51 if(handle >= count || handle < 0) return 1;
52 items[handle] = data;
53 return 0;
54 }
55
56 int List::search_item(void * item)
57 {
58 int i;
59 for (i = 0;i < count && items[i] != item;i++);
60 return (i == count)? -1:i;
61 }
62
63 int List::delete_item(int handle)
64 {
65 g_return_val_if_fail(handle < count && handle >= 0, 1);
66 if(handle != count-1) memmove(items+handle,
67 items+(handle+1),
68 (count-handle-1)*sizeof(void*));
69 count--;
70 return 0;
71 }
72
73 void List::insert_item(int handle, void * item)
74 {
75 int i;
76 if(!items) {
77 items = (void **)malloc(sizeof(void*)*LIST_INIT_SIZE);
78 if(!items) {
79 perror("class List: can not malloc mem when init:");
80 exit(1);
81 }
82 buffer_length = LIST_INIT_SIZE;
83 }
84 else if(buffer_length == count){
85 items = (void **)realloc((void*)items,sizeof(void *)*(buffer_length+=buffer_length));
86 if(!items){
87 perror("class List: mem not enought when realloc:");
88 exit(1);
89 }
90 }
91 if(handle >= count)
92 items[count++] = item;
93 else {
94 handle = handle <0? 0:handle;
95 for(i = count++;i>handle;i--)
96 items[i] = items[i-1];
97 items[handle] = item;
98 }
99 }
100
101 void List::delete_all()
102 {
103 count = 0;
104 }
105
106 int List::get_items(void * buffer)
107 {
108 memcpy((void *)buffer,(void *)items,count*sizeof(void*));
109 return count;
110 }
111
112 int List::get_size()
113 {
114 return count;
115 }
116
117 int List::meet_end(int handle)
118 {
119 return (handle >= count)? 1:0;
120 }
121
122 /********************* class Dictionary ***************/
123
124 Dictionary::Dictionary()
125 {
126 names = new List;
127 values = new List;
128 }
129
130 Dictionary::~Dictionary()
131 {
132 delete(names);
133 delete(values);
134 }
135
136 void Dictionary::add_item(char * name,void * value)
137 {
138 int i;
139 if((i = search_item(name)) != -1) {
140 values->reset_item(i,value);
141 }
142 else {
143 names->add_item(name);
144 values->add_item(value);
145 }
146 }
147
148 int Dictionary::search_item(char * name)
149 {
150 int i,j;
151 j = names->get_size();
152 for(i = 0;i<j && strcmp(name,(char*)names->get_item(i));i++);
153 return (i==j)? -1:i;
154 }
155
156 int Dictionary::have_item(char * name)
157 {
158 return search_item(name) != -1;
159 }
160
161 void * Dictionary::get_value(char * name)
162 {
163 int i;
164 i = names->search_item(name);
165 return (i==-1)? NULL:values->get_item(i);
166 }
167
168 int Dictionary::get_size()
169 {
170 return names->get_size();
171 }
172
173 void * Dictionary::get_value(int i)
174 {
175 return values->get_item(i);
176 }
177
178 char * Dictionary::get_name(int i)
179 {
180 return (char*)names->get_item(i);
181 }
182
183 void Dictionary::set_value(int i, void * value)
184 {
185 values->reset_item(i,value);
186 }
187
188 void Dictionary::delete_item(int i)
189 {
190 names->delete_item(i);
191 values->delete_item(i);
192 }
193
194 void Dictionary::display_items()
195 {
196 int i,j;
197 j = names->get_size();
198 for(i = 0;i<j;i++)
199 printf("%s\n",names->get_item(i));
200 }
201
202
203
0 /******************** list.h *****************/
1 /******************** 1999.6.13 *************/
2
3 #ifndef _LIST_H
4 #define _LIST_H
5
6 class List
7 {
8 private:
9 void ** items;
10 int buffer_length;
11 int count;
12 public:
13 List();
14 ~List();
15 void add_item(void * item);
16 void * get_item(int handle);
17 int reset_item(int handle,void * item);
18 int search_item(void * item);
19 int delete_item(int handle);
20 void insert_item(int handle, void * item);
21 void delete_all();
22 int get_size();
23 int get_items(void * buffer);
24 int meet_end(int handle);
25 };
26
27 class Dictionary
28 {
29 private:
30 List * names;
31 List * values;
32 public:
33 Dictionary();
34 ~Dictionary();
35 void add_item(char * name,void * value);
36 int have_item(char * name);
37 int search_item(char * name);
38 void * get_value(char* name);
39 int get_size();
40 void * get_value(int i);
41 char * get_name(int i);
42 void set_value(int i,void * value);
43 void delete_item(int i);
44 void display_items();
45 };
46
47 #endif
48
49
50
51
52
53
54
55
56
57
0 /********************** modified from t2.c *******************/
1 /********************* kman.c ********************************/
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #ifdef SYS_DIR
7 #include <sys_dir.h>
8 #else
9 #ifdef NDIR
10
11 #include <ndir.h>
12 #else
13 #include <dirent.h>
14 #endif
15 #endif
16
17 #include <sys/stat.h>
18 #include <unistd.h>
19 #include <errno.h>
20
21 #include "mandata.h"
22 #include "mandatadef.h"
23 #include "util.h"
24 #include "context.h"
25 #include "gman.h"
26
27 #include <stdlib.h>
28
29 void attach (char *dest, const char *dirname, const char *name);
30 static int section_translate_c_to_n(const char* c);
31 static int ManItemComp(ManItem ** a,ManItem ** b);
32 static int is_zip_suffix(char* c);
33
34 char buffer1[BUFFER_SIZE];
35 char buffer2[BUFFER_SIZE];
36
37 /************************* ManPath ************************/
38 ManPath::ManPath(char* _path_name)
39 {
40 int i;
41 int len;
42 active = 1;
43 path_name = my_strdup(_path_name);
44 for (i=0;i<MAX_MAN_SECTION;i++) section[i] = new List();
45 LoadManPath(path_name);
46 }
47
48 ManPath::~ManPath()
49 {
50 int i,j,k;
51 for (i = 0;i<MAX_MAN_SECTION;i++) {
52 k = section[i]->get_size();
53 for(j = 0;j<k;j++) delete ((ManItem*)(section[i]->get_item(j)));
54 delete(section[i]);
55 }
56 if(path_name) free(path_name);
57 }
58
59 ManPath::GetSize(int section_ID)
60 {
61 int count;
62 int i;
63 for (count = i = 0;i<MAX_MAN_SECTION;i++)
64 if (1<<i & section_ID) count += section[i]->get_size();
65 return count;
66 }
67
68 ManPath::GetItems(int section_ID, ManItem * buffer[])
69 {
70 int count;
71 int i;
72 for (count = i = 0;i<MAX_MAN_SECTION;i++)
73 if (1<<i & section_ID) count += section[i]->get_items((void*)(buffer + count));
74 return count;
75 }
76
77 const char * ManPath::GetPath() {return (const char*) path_name;}
78
79 struct stat state;
80
81 ManPath::LoadManPath(char * path_name)
82 {
83 DIR *dirp;
84 #if defined(SYS_DIR)||defined(NDIR)
85 struct direct *item;
86 #else
87 struct dirent *item;
88 #endif
89
90 ManItem * man_item;
91 int val,i;
92
93 // printf("LoadManPath: %s\n",path_name);
94
95 dirp = opendir(path_name);
96 if (!dirp)
97 {
98 fprintf(stderr,"Can not open man path %s\n",path_name);
99 return 1;
100 }
101 for (item = readdir(dirp);item != NULL;item = readdir(dirp))
102 {
103 if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0)))
104 continue;
105 attach(buffer1,path_name,item->d_name);
106 //printf("LoadManPath: %s\n",name);
107 val = stat (buffer1, &state);
108 if (val < 0) fprintf(stderr,"error number %d, in get state %s",errno,buffer1);
109 else if (S_ISDIR(state.st_mode) && !strncmp(item->d_name,"man",3)) LoadManSubPath(item->d_name);
110 else
111 {
112 man_item = new ManItem(this,item -> d_name);
113 val = man_item->get_section_ID();
114 if(!val) delete(man_item);
115 else{
116 for(i = 0;!(1<<i & val);i++);
117 section[i]->add_item(man_item);
118 }
119 //printf("%d\n",n);
120 }
121 }
122 closedir(dirp);
123 return 0;
124 }
125
126 ManPath::LoadManSubPath(char * sub_name)
127 {
128 DIR *dirp;
129 #if defined(SYS_DIR)||defined(NDIR)
130 struct direct *item;
131 #else
132 struct dirent *item;
133 #endif
134
135 int val,i;
136 ManItem * man_item;
137
138 attach(buffer2,path_name,sub_name);
139 //printf("LoadManSubPath: %s\n",buffer2);
140 dirp = opendir(buffer2);
141 if (!dirp)
142 {
143 fprintf(stderr,"Can not open man path %s\n",buffer2);
144 }
145 for (item = readdir(dirp);item != NULL;item = readdir(dirp))
146 {
147 if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0)))
148 continue;
149 attach(buffer1,buffer2,item->d_name);
150 //printf("LoadManSubPath: %s\n",full_name);
151 val = stat (buffer1, &state);
152 if (val < 0) fprintf(stderr,"error number %d, in get state %s\n",errno,buffer1);
153 else if (S_ISDIR(state.st_mode)) continue;
154 else
155 {
156 attach(buffer1,sub_name,item->d_name);
157 man_item = new ManItem(this,buffer1);
158 val = man_item->get_section_ID();
159 if(!val) delete(man_item);
160 else{
161 for(i = 0;!(1<<i & val);i++);
162 section[i]->add_item(man_item);
163 }
164 }
165 }
166 closedir(dirp);
167 }
168
169 ManItem * ManPath::search_man_item(char * name, char * sect)
170 {
171 int i,j,k;
172 int len;
173 ManItem * a;
174 char buffer[100];
175
176 len = strlen(name);
177 if(section) {
178 j = section_translate_c_to_n(sect);
179 //printf("point0.1\n");
180 if(!j) return NULL;
181 for(i = 0;!(1<<i & j);i++);
182 //printf("point0.2, section = %x,%d: section[i] = %x\n", j,i,section[i]);
183 k = section[i]->get_size();
184 //printf("point0.25, k = %d\n",k);
185 for(j = 0;j<k;j++) {
186 a=(ManItem*)(section[i]->get_item(j));
187 if(!strcmp(name,a->get_display_name(buffer))) return a;
188 }
189 a = NULL;
190 }
191 return NULL;
192 }
193
194 /************************* ManItem ************************/
195 inline ManItem::ManItem(ManPath* _man_path, char* _file_name)
196 {
197 file_name = my_strdup(_file_name);
198 man_path = _man_path;
199 display_name = strrchr(file_name,'/');
200 display_name = display_name? display_name + sizeof('/'):file_name;
201 section_name = strrchr(display_name,'.');
202 if (!section_name) { section_ID = 0; return;}
203 for (;is_zip_suffix(section_name) && section_name != display_name;)
204 for(section_name--;section_name != display_name && *section_name != '.';section_name --);
205 if (section_name == display_name) {section_ID = 0; return;}
206 section_ID = section_translate_c_to_n(++section_name);
207 //if(!section_ID) printf("%s\n",display_name);
208 }
209
210 inline ManItem::~ManItem()
211 {
212 if(file_name) free(file_name);
213 }
214
215 char * ManItem::get_display_name(char * buffer)
216 {
217 char * p2 = buffer;
218 for(char * p = display_name;p+1 != section_name && *p != '\0';) *buffer++ = *p++;
219 *buffer = '\0';
220 return p2;
221 }
222
223 char * ManItem::get_section_name(char * buffer)
224 {
225 char * p2 = buffer;
226 for(char * p = section_name;*p != '.' && *p != '\0';) *buffer++ = *p++;
227 *buffer = '\0';
228 return p2;
229 }
230
231 int ManItem::get_section_ID() {return section_ID;}
232
233 void * ManItem::get_man_path() {return (void *)man_path;}
234
235 void ManItem::active_man_page(void)
236 {
237 int i;
238 int len;
239 char buffer[BUFFER_SIZE];
240 sprintf(buffer,"%s -T '%s' -n GMan -e man ",
241 (char*)context->get_value("xterm_command"),
242 get_display_name(buffer1));
243 len = strlen(buffer);
244 attach(buffer+len,man_path->GetPath(),file_name);
245 //printf(buffer);
246
247 if(!fork())
248 {
249 //printf(buffer);
250 system(buffer);
251 _exit(0);
252 }
253
254 return;
255 }
256
257 /************************* init global data ************************/
258
259 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
260
261 void attach (char *dest, const char *dirname, const char *name)
262 {
263 const char *dirnamep = dirname;
264
265 /* Copy dirname if it is not ".". */
266 if (dirname[0] != '.' || dirname[1] != 0)
267 {
268 while (*dirnamep) *dest++ = *dirnamep++;
269 /* Add '/' if `dirname' doesn't already end with it. */
270 if (dirnamep > dirname && dirnamep[-1] != '/') *dest++ = '/';
271 }
272 while (*name) *dest++ = *name++;
273 *dest = 0;
274 }
275
276 int section_translate_c_to_n(const char *c)
277 {
278 int i;
279 for(i=0;sections[i].name && strncmp(sections[i].name,c,sections[i].n);i++);
280 if(sections[i].name == NULL) return 0; // no match
281 return 1<<i;
282 }
283
284 int is_zip_suffix(char * s)
285 {
286 int i;
287 for (i=0;suffix[i].name && strncmp(suffix[i].name,s,suffix[i].n);i++);
288 return suffix[i].n;
289 }
290
291 int man_item_compare(ManItem ** a,ManItem ** b)
292 {
293 return (strcmp((*a)->get_display_name(buffer1),(*b)->get_display_name(buffer2)));
294 }
295
296 /*
297 int ItemMatch(char * name)
298 {
299 int i;
300 for (i=0;i<item_list_count && strcmp(name,item_list[i]->display_name)>0 ;i++);
301 return (i >= item_list_count)? i-1:i;
302 }
303 */
304
305
0 /********************** modified from t2.c *******************/
1 /********************* kman.h ********************************/
2 #include "list.h"
3
4 #ifndef _KMAN_H
5 #define _KMAN_H
6
7 #define MAX_MAN_SECTION 15
8 #define BUFFER_SIZE 200
9
10 class ManPath;
11 class ManItem;
12
13 class ManPath
14 {
15 private:
16 char * path_name;
17 List * section[MAX_MAN_SECTION]; //1:2:3:4:5:6:7:8:9:tcl:n:l:p:o
18 private:
19 LoadManSubPath(char *);
20 public:
21 int active;
22 ManPath(char * path_name);
23 ~ManPath();
24 LoadManPath(char *);
25 const char * GetPath();
26 int GetSize(int section_ID);
27 int GetItems(int section_ID, ManItem **buffer);
28 ManItem * search_man_item(char * name, char * section);
29 };
30
31 class ManItem
32 {
33 public:
34 ManItem(ManPath *, char * file_name);
35 ~ManItem();
36 char * get_display_name(char * buffer);
37 char * get_section_name(char * buffer);
38 int get_section_ID();
39 void * get_man_path();
40 void active_man_page();
41 private:
42 ManPath * man_path;
43 char * file_name;
44 char * display_name;
45 char * section_name;
46 int section_ID;
47 };
48
49 //int ItemMatch(char * name);
50 int man_item_compare(ManItem **,ManItem **);
51 void attach (char *dest, const char *dirname, const char *name);
52
53 #endif /* _KMAN_H */
54
55
0 struct data_pair
1 {
2 char * name;
3 int n;
4 };
5
6 #define MAX_MAN_SECTION 15
7
8 data_pair sections[]=
9 {
10 {"1",1},
11 {"2",1},
12 {"3",1},
13 {"4",1},
14 {"5",1},
15 {"6",1},
16 {"7",1},
17 {"8",1},
18 {"l",1},
19 {"n",1},
20 {"9",1},
21 {"tcl",3},
22 {"p",1},
23 {"o",1},
24 {NULL,0}
25 };
26
27 data_pair suffix[]=
28 {
29 {".gz",3},
30 {".bz2",4},
31 {".z",2},
32 {".Z",2},
33 {".F",2},
34 {".Y",2},
35 {NULL,0}
36 };
37
0 /********************** modified from t2.c *******************/
1 /********************* menu.c ********************************/
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <strings.h>
6 #include <sys/types.h>
7 #ifdef SYS_DIR
8 #include <sys_dir.h>
9 #else
10 #ifdef NDIR
11 #include <ndir.h>
12 #else
13 #include <dirent.h>
14 #endif
15 #endif
16
17 #include <sys/stat.h>
18 #include <unistd.h>
19 #include <errno.h>
20
21 #include <stdlib.h>
22
23 #include <gtk/gtk.h>
24
25 #include <libintl.h>
26
27 #include "mandata.h"
28 #include "util.h"
29 #include "gman.h"
30 #include "list.h"
31 #include "task.h"
32 #include "window2.h"
33 #include "taskfunc.h"
34
35 static int print_hello(GtkWidget *w, gpointer data);
36 static int test_callback(GtkWidget *w, gpointer data);
37 static int window_resize_callback(GtkWidget *w, GtkAllocation *size, gpointer data);
38 static int section_policy_callback(GtkWidget *w, gpointer data);
39 static int section_select_callback(GtkWidget *w, gpointer data);
40 static int status_bar_callback (GtkWidget *widget, gpointer data);
41 static int search_mode_callback (GtkWidget *widget, gpointer data);
42 static void app_quit(GtkWidget *w, gpointer data);
43 static void select_row_callback(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
44 static void select_row_callback3(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
45 static void entry_activate_callback(GtkWidget *,gpointer);
46 static void entry_changed_callback(GtkWidget *,gpointer);
47 static void window_help_about_callback (GtkWidget *widget, gpointer data);
48 static void entry4_activate_callback(GtkWidget *,gpointer);
49 static void entry4_changed_callback(GtkWidget *,gpointer);
50 static int button_clicked_callback(GtkWidget *,gpointer);
51
52 #define MAX_PATHS 10
53
54 #define MENU_DISPLAY_POSITION 201
55 #define MENU_NEXT_POSITION 202
56
57 #define _(string) gettext(string)
58
59 static GtkItemFactoryEntry menu_items[] = {
60 {"/_File", NULL, NULL, 0, "<Branch>"},
61 {"/File/_Quit", "<control>Q", (void (*)(...))app_quit, 0, NULL},
62 {"/_Sections", NULL, NULL, 0, "<Branch>"},
63 {"/Sections/tearoff1", NULL, NULL, 0, "<Tearoff>" },
64 {"/Sections/_All", NULL, (void (*)(...))section_policy_callback, 0, "<RadioItem>"},
65 {"/Sections/all _But", NULL, (void (*)(...))section_policy_callback, 1, "/Sections/All"},
66 {"/Sections/_Only", NULL, (void (*)(...))section_policy_callback, 2, "/Sections/All"},
67 {"/Sections/sep1", NULL, NULL, 0, "<Separator>"},
68 {"/Sections/_1: User Commands", NULL, (void (*)(...))section_select_callback, 1<<0, "<CheckItem>"},
69 {"/Sections/_2: System Calls", NULL, (void (*)(...))section_select_callback, 1<<1, "<CheckItem>"},
70 {"/Sections/_3: Subroutines", NULL, (void (*)(...))section_select_callback, 1<<2, "<CheckItem>"},
71 {"/Sections/_4: Devices", NULL, (void (*)(...))section_select_callback, 1<<3, "<CheckItem>"},
72 {"/Sections/_5: File Formats", NULL, (void (*)(...))section_select_callback, 1<<4, "<CheckItem>"},
73 {"/Sections/_6: Games", NULL, (void (*)(...))section_select_callback, 1<<5, "<CheckItem>"},
74 {"/Sections/_7: Miscellaneous", NULL, (void (*)(...))section_select_callback, 1<<6, "<CheckItem>"},
75 {"/Sections/_8: Sys.Administration",NULL, (void (*)(...))section_select_callback, 1<<7, "<CheckItem>"},
76 {"/Sections/_l: Local", NULL, (void (*)(...))section_select_callback, 1<<8, "<CheckItem>"},
77 {"/Sections/_n: New", NULL, (void (*)(...))section_select_callback, 1<<9, "<CheckItem>"},
78 {"/_Options", NULL, NULL, 0, "<Branch>"},
79 {"/Options/Status bar", NULL, (void (*)(...))status_bar_callback, 0, "<CheckItem>"},
80 {"/Options/sep1", NULL, NULL, 0, "<Separator>"},
81 {"/Options/_Index search", NULL, (void (*)(...))search_mode_callback, 0, "<RadioItem>"},
82 {"/Options/_Key word search", NULL, (void (*)(...))search_mode_callback, 1, "/Options/Index search"},
83 {"/Options/sep2", NULL, NULL, 0, "<Separator>"},
84 {"/Options/Man _Paths...", "<control>P", (void (*)(...))edit_paths_callback, 0, NULL},
85 // {"/Options/Test", NULL, (void (*)(...))test_callback, 0, NULL},
86 {"/_Help", NULL, NULL, 0, "<LastBranch>"},
87 {"/_Help/About", NULL, GTK_SIGNAL_FUNC(window_help_about_callback),0,NULL}
88 };
89
90 /********************* init_main_window *************************/
91
92 GtkWidget * clist;
93 GtkWidget * entry;
94 GtkWidget * clist3;
95 GtkWidget * window; //main window
96 GtkTooltips * tooltips;
97
98 GtkWidget * section_buttons[MAX_MAN_SECTION];
99 GtkWidget * section_select[3];
100 GtkWidget * searching_mode_buttons[2];
101 GtkWidget * status_bar_button;
102
103 int signal_select_row; //used by select_row_callback() to decide whether to active man pages
104 int signal_entry_change; //used by entry_changed_callback() to decide whether to refresh list
105 int signal_menu_change; //used by menu_item callback to decide whether to take action or not
106 Dictionary * man_paths;
107 char * *man_items_buffer;
108 int man_items_count;
109 int clist_selected_row;
110 List * man_paths_to_be_load;
111 char * keyword;
112
113 void updata_menu_buttons(int);
114
115 void get_main_menu(GtkWidget *window, GtkWidget ** menubar) {
116 int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
117 GtkItemFactory *item_factory;
118 GtkAccelGroup *accel_group;
119
120 accel_group = gtk_accel_group_new();
121
122 /* This function initializes the item factory.
123 Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
124 or GTK_TYPE_OPTION_MENU.
125 Param 2: The path of the menu.
126 Param 3: A pointer to a gtk_accel_group. The item factory sets up
127 the accelerator table while generating menus.
128 */
129
130 item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>",
131 accel_group);
132
133 /* This function generates the menu items. Pass the item factory,
134 the number of items in the array, the array itself, and any
135 callback data for the the menu items. */
136 gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL);
137
138 /* Attach the new accelerator group to the window. */
139 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
140
141 if (menubar)
142 /* Finally, return the actual menu bar created by the item factory. */
143 *menubar = gtk_item_factory_get_widget(item_factory, "<main>");
144 section_select[0] = gtk_item_factory_get_widget(item_factory, "/Sections/All");
145 section_select[1] = gtk_item_factory_get_widget(item_factory, "/Sections/all But");
146 section_select[2] = gtk_item_factory_get_widget(item_factory, "/Sections/Only");
147 section_buttons[0] = gtk_item_factory_get_widget(item_factory, "/Sections/1: User Commands");
148 section_buttons[1] = gtk_item_factory_get_widget(item_factory, "/Sections/2: System Calls");
149 section_buttons[2] = gtk_item_factory_get_widget(item_factory, "/Sections/3: Subroutines");
150 section_buttons[3] = gtk_item_factory_get_widget(item_factory, "/Sections/4: Devices");
151 section_buttons[4] = gtk_item_factory_get_widget(item_factory, "/Sections/5: File Formats");
152 section_buttons[5] = gtk_item_factory_get_widget(item_factory, "/Sections/6: Games");
153 section_buttons[6] = gtk_item_factory_get_widget(item_factory, "/Sections/7: Miscellaneous");
154 section_buttons[7] = gtk_item_factory_get_widget(item_factory, "/Sections/8: Sys.Administration");
155 section_buttons[8] = gtk_item_factory_get_widget(item_factory, "/Sections/l: Local");
156 section_buttons[9] = gtk_item_factory_get_widget(item_factory, "/Sections/n: New");
157 searching_mode_buttons[0] = gtk_item_factory_get_widget(item_factory, "/Options/Index search");
158 searching_mode_buttons[1] = gtk_item_factory_get_widget(item_factory, "/Options/Key word search");
159 status_bar_button = gtk_item_factory_get_widget(item_factory, "/Options/Status bar");
160 // gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_buttons[4]),1);
161 updata_menu_buttons(0);
162 }
163
164 /*flag = 0 means not to invoke call backs when changing the states of buttons.*/
165 void updata_menu_buttons(int flag)
166 {
167 int i,j,k,k2;
168 k = (int)context->get_value("display_section_policy");
169 if(k>0 && k<=2)
170 if(!((GtkCheckMenuItem*)(section_select[k]))->active){
171 if(!flag) signal_menu_change++;
172 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_select[k]),1);
173 }
174 k = (int)context->get_value("display_section");
175 for (i = 0;i<10;i++)
176 if(!(k&(1<<i)) != !(((GtkCheckMenuItem*)(section_buttons[i]))->active)) {
177 if(!flag) signal_menu_change++;
178 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_buttons[i]),k&(1<<i));
179 }
180 k = (int)context->get_value("searching_mode");
181 if(k>0 && k<=1)
182 if(!(((GtkCheckMenuItem*)(searching_mode_buttons[k]))->active)) {
183 if(!flag) signal_menu_change++;
184 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(searching_mode_buttons[k]),1);
185 }
186 k2 = (int)context->get_value("show_status_bar");
187 i = k2&(1<<k);
188 j = (((GtkCheckMenuItem*)(status_bar_button))->active);
189 if((i&&!j) || (!i&&j)) {
190 if(!flag) signal_menu_change++;
191 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(status_bar_button),i);
192 }
193 gtk_widget_hide(status_bar_button);
194 }
195
196 static GtkWidget *index_search_vbox;
197 static GtkWidget *keyword_search_vbox;
198 static GtkWidget *hbox4;
199 static GtkWidget *hbox_status;
200 static GtkWidget *entry4;
201 GtkWidget *search_button;
202 GtkWidget *stop_button;
203 static GtkWidget *statusbar1;
204 static GtkWidget *statusbar2;
205
206 static void updata_widget_show(int flag)
207 {
208 int k,k2;
209
210 k = (int)context->get_value("searching_mode");
211 k2 = (int)context->get_value("show_status_bar");
212
213 if(k2&(1<<k))
214 gtk_widget_show(hbox_status);
215 else
216 gtk_widget_hide(hbox_status);
217 gtk_widget_hide(!k?keyword_search_vbox:index_search_vbox);
218 gtk_widget_show(k?keyword_search_vbox:index_search_vbox);
219 if(k2 & (1<<k)) gtk_widget_show (hbox_status);
220 }
221
222
223 void init_main_window(GtkWidget * window)
224 {
225 GtkWidget * main_vbox;
226 GtkWidget * menubar;
227 GtkWidget * swindow;
228 GtkWidget * swindow2;
229 GtkWidget * focus;
230
231 int k,k2;
232
233 ::window = window;
234 gchar *titles[2] = { "Name", "Section" };
235 gchar *titles2[3] = { "Name", "Section", "Description"};
236 signal_select_row = 0;
237 signal_entry_change = 0;
238
239 tooltips = gtk_tooltips_new();
240
241 gtk_signal_connect(GTK_OBJECT(window), "destroy",
242 GTK_SIGNAL_FUNC(app_quit),
243 0);
244
245 gtk_window_set_title(GTK_WINDOW(window), "G-man");
246 gtk_window_set_policy( GTK_WINDOW( window ), FALSE, TRUE, FALSE );
247 gtk_window_set_default_size(GTK_WINDOW(window),
248 (int)context->get_value("h_size"),
249 (int)context->get_value("v_size"));
250
251 gtk_widget_set_usize(GTK_WIDGET(window),200,150);
252 main_vbox = gtk_vbox_new(FALSE, 1);
253 gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
254 gtk_container_add(GTK_CONTAINER(window), main_vbox);
255 gtk_widget_show(main_vbox);
256
257 get_main_menu(window, &menubar);
258 gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
259 gtk_widget_show(menubar);
260
261 gtk_signal_connect(GTK_OBJECT(window),"size_allocate",GTK_SIGNAL_FUNC(window_resize_callback),NULL);
262
263 //keyword_search_vbox
264 keyword_search_vbox = gtk_vbox_new(FALSE,1);
265 gtk_box_pack_start(GTK_BOX(main_vbox), keyword_search_vbox, TRUE, TRUE, 0);
266
267 hbox4 = gtk_hbox_new (FALSE, 1);
268 gtk_object_set_data (GTK_OBJECT (window), "hbox4", hbox4);
269 gtk_box_pack_start (GTK_BOX (keyword_search_vbox), hbox4, FALSE, TRUE, 0);
270 gtk_widget_show (hbox4);
271
272 stop_button = gtk_button_new_with_label ("Stop");
273 gtk_object_set_data (GTK_OBJECT (window), "stop_button", stop_button);
274 gtk_widget_set_sensitive(stop_button,0);
275 gtk_signal_connect (GTK_OBJECT(stop_button),"clicked",(GtkSignalFunc)button_clicked_callback,(void*)1);
276 gtk_widget_show (stop_button);
277 gtk_box_pack_start (GTK_BOX (hbox4), stop_button, FALSE, TRUE, 0);
278 gtk_widget_set_usize (stop_button, 40, -2);
279
280 entry4 = gtk_entry_new ();
281 gtk_object_set_data (GTK_OBJECT (window), "entry4", entry4);
282 gtk_widget_show (entry4);
283 gtk_tooltips_set_tip (tooltips, entry4, "Key word search", NULL);
284 gtk_box_pack_start (GTK_BOX (hbox4), entry4, TRUE, TRUE, 0);
285 gtk_signal_connect(GTK_OBJECT(entry4), "activate",
286 GTK_SIGNAL_FUNC(entry4_activate_callback),NULL);
287 gtk_signal_connect(GTK_OBJECT(entry4), "changed",
288 GTK_SIGNAL_FUNC(entry4_changed_callback),NULL);
289
290 search_button = gtk_button_new_with_label ("Search");
291 gtk_object_set_data (GTK_OBJECT (window), "search_button", search_button);
292 gtk_widget_set_sensitive(search_button,0);
293 gtk_signal_connect (GTK_OBJECT(stop_button),"clicked",(GtkSignalFunc)button_clicked_callback,(void*)2);
294 gtk_widget_show (search_button);
295 gtk_box_pack_start (GTK_BOX (hbox4), search_button, FALSE, TRUE, 0);
296 gtk_widget_set_usize (search_button, 60, -2);
297
298
299 clist3 = gtk_clist_new_with_titles( 3, titles2);
300 swindow2 = gtk_scrolled_window_new (NULL, NULL);
301 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow2),
302 GTK_POLICY_AUTOMATIC,
303 GTK_POLICY_AUTOMATIC);
304
305
306 gtk_clist_set_column_width(GTK_CLIST(clist3),0,100);
307 gtk_clist_set_selection_mode(GTK_CLIST(clist3),GTK_SELECTION_SINGLE);
308 gtk_clist_column_titles_passive(GTK_CLIST(clist3));
309 gtk_clist_set_column_auto_resize (GTK_CLIST(clist3),2,1);
310
311 gtk_container_add (GTK_CONTAINER (swindow2), clist3);
312 gtk_box_pack_start (GTK_BOX (keyword_search_vbox), swindow2, TRUE, TRUE, 0);
313 gtk_widget_show_all(GTK_WIDGET(swindow2));
314
315 gtk_signal_connect(GTK_OBJECT(clist3),"select_row",
316 GTK_SIGNAL_FUNC(select_row_callback3),NULL);
317
318 //index_search_vbox
319 index_search_vbox = gtk_vbox_new(FALSE,1);
320 gtk_box_pack_start(GTK_BOX(main_vbox), index_search_vbox, TRUE, TRUE, 0);
321 entry = gtk_entry_new_with_max_length (50);
322 clist = gtk_clist_new_with_titles( 2, titles);
323 gtk_signal_connect(GTK_OBJECT(entry), "activate",
324 GTK_SIGNAL_FUNC(entry_activate_callback),
325 (gpointer)clist);
326 gtk_signal_connect(GTK_OBJECT(entry), "changed",
327 GTK_SIGNAL_FUNC(entry_changed_callback),
328 (gpointer)clist);
329 gtk_box_pack_start (GTK_BOX (index_search_vbox), entry, FALSE, TRUE, 0);
330 gtk_tooltips_set_tip (tooltips, entry, "index search", NULL);
331 gtk_widget_show(entry);
332
333 swindow = gtk_scrolled_window_new (NULL, NULL);
334 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
335 GTK_POLICY_AUTOMATIC,
336 GTK_POLICY_AUTOMATIC);
337
338
339 gtk_clist_set_column_width(GTK_CLIST(clist),0,200);
340 gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE);
341 gtk_clist_column_titles_passive(GTK_CLIST(clist));
342 gtk_container_add (GTK_CONTAINER (swindow), clist);
343 gtk_box_pack_start (GTK_BOX (index_search_vbox), swindow, TRUE, TRUE, 0);
344
345 gtk_signal_connect(GTK_OBJECT(clist),"select_row",
346 GTK_SIGNAL_FUNC(select_row_callback),NULL);
347
348 focus = entry;
349 gtk_widget_grab_focus (focus);
350 gtk_widget_show_all (swindow);
351
352 hbox_status = gtk_hbox_new (FALSE, 0);
353 gtk_object_set_data (GTK_OBJECT (window), "hbox_status", hbox_status);
354 gtk_box_pack_start (GTK_BOX (main_vbox), hbox_status, FALSE, TRUE, 0);
355
356 updata_widget_show(0);
357
358 statusbar1 = gtk_statusbar_new ();
359 gtk_object_set_data (GTK_OBJECT (window), "statusbar1", statusbar1);
360 gtk_widget_show (statusbar1);
361 gtk_box_pack_start (GTK_BOX (hbox_status), statusbar1, TRUE, TRUE, 0);
362
363 statusbar2 = gtk_statusbar_new ();
364 gtk_object_set_data (GTK_OBJECT (window), "statusbar2", statusbar2);
365 gtk_widget_show (statusbar2);
366 gtk_box_pack_start (GTK_BOX (hbox_status), statusbar2, FALSE, TRUE, 0);
367 }
368
369
370 /******************* tools functions ******************/
371 int search_array_for_text(char ** array, int count, char * text)
372 {
373 int i;
374 for (i=0;i<count && strcmp(text,array[i])>0 ;i++);
375 return (i >= count)? i-1:i;
376 }
377
378 /******************* call backs ***********************/
379 void select_row_callback(GtkWidget *widget,
380 gint row,
381 gint column,
382 GdkEventButton *event,
383 gpointer data)
384 {
385 ManItem * item;
386 if(signal_select_row>0) {signal_select_row--;return;}
387 item = (ManItem*) gtk_clist_get_row_data(GTK_CLIST(widget),row);
388 item->active_man_page();
389 signal_entry_change++;
390 gtk_entry_set_text(GTK_ENTRY(entry),man_items_buffer[row]);
391 }
392 void select_row_callback3(GtkWidget *widget,
393 gint row,
394 gint column,
395 GdkEventButton *event,
396 gpointer data)
397 {
398 ManItem * item;
399 if(signal_select_row>0) {signal_select_row--;return;}
400 item = (ManItem*) gtk_clist_get_row_data(GTK_CLIST(widget),row);
401 if(item) item->active_man_page();
402 }
403 void entry_activate_callback(GtkWidget * w,gpointer data)
404 {
405 int i;
406 GtkWidget * clist = (GtkWidget *)data;
407 i = search_array_for_text(man_items_buffer,
408 man_items_count,
409 gtk_entry_get_text(GTK_ENTRY(w)));
410 if (i == -1) return;
411 gtk_clist_moveto(GTK_CLIST(clist),i,0,0.1,0.0);
412 GTK_CLIST(clist)->focus_row = i;
413 gtk_clist_select_row(GTK_CLIST(clist),i,0);
414 }
415
416 void entry_changed_callback(GtkWidget * w,gpointer data)
417 {
418 int i;
419 GtkWidget * clist = (GtkWidget *)data;
420 if(signal_entry_change>0) {signal_entry_change--;return;}
421 i = search_array_for_text(man_items_buffer,
422 man_items_count,
423 gtk_entry_get_text(GTK_ENTRY(w)));
424 if (i == -1) return;
425 signal_select_row++;
426 gtk_clist_moveto(GTK_CLIST(clist),i,0,0.1,0.0);
427 GTK_CLIST(clist)->focus_row = i;
428 gtk_clist_select_row(GTK_CLIST(clist),i,0);
429 }
430
431 static int print_hello(GtkWidget *w, gpointer data) {
432 if(signal_menu_change>0) {signal_menu_change--;return 1;}
433 g_message("Hello, World! %x\n",data);
434 return 0;
435 }
436
437 static int test_callback(GtkWidget *w, gpointer data) {
438 int i,j;
439 if(signal_menu_change>0) {signal_menu_change--;return 1;}
440 j = man_paths->get_size();
441 for(i = 0;i<j;i++)
442 delete ((ManPath*)(man_paths->get_value(i)));
443 delete (man_paths);
444 init_man_data();
445 return 0;
446 }
447
448 static int section_policy_callback(GtkWidget *w, gpointer data) {
449 // static int signal;
450 int k,k2;
451 k2 = (int) data;
452 if(!((GtkCheckMenuItem*)(section_select[k2]))->active) return 1;
453 // g_message("Hello, World! %x\n signal = %d",data,signal_menu_change);
454 if(signal_menu_change>0) {signal_menu_change--;return 1;}
455 //if(!signal) {signal++;return 1;}
456 //signal--;
457 k = (int) context->get_value("display_section_policy");
458 if(k == k2) return 1;
459 pthread_mutex_lock(&context_lock);
460 context->set_value("display_section_policy","int",(void*)k2);
461 pthread_mutex_unlock(&context_lock);
462 task_set_active(task_extract_man_data);
463 task_set_active(task_add_data_to_clist);
464 }
465
466 static int section_select_callback(GtkWidget *w, gpointer data) {
467 int var;
468 if(signal_menu_change>0) {signal_menu_change--;return 1;}
469
470 pthread_mutex_lock(&context_lock);
471 var = (int)context->get_value("display_section");
472 var ^= (int)data;
473 context->set_value("display_section","int",(void*)var);
474 if (context->get_value("display_section_policy")) {
475 task_set_active(task_extract_man_data);
476 task_set_active(task_add_data_to_clist);
477 }
478 pthread_mutex_unlock(&context_lock);
479 // g_message("Hello, World! %x\n",data);
480 }
481
482 static void app_quit(GtkWidget *w, gpointer data) {
483 // g_message("Bye, World! %x\n",data);
484 char buffer[1024],*p;
485 FILE * fd;
486 int i,j;
487 p = buffer;
488 j = man_paths->get_size();
489 for (i = 0;i<j;i++) {
490 sprintf(p,i?":%s":"%s",man_paths->get_name(i));
491 for(;*p;p++);
492 }
493 context->set_value("man_paths","char*",my_strdup(buffer));
494 attach(buffer,getenv("HOME"),".gman");
495 if((fd = fopen(buffer,"w"))) {
496 context->save(fd,"automatically made by G-man");
497 fclose(fd);
498 }
499 // context->save(stdout,"automatically made by G-man");
500
501 gtk_exit((int)data);
502 }
503
504 static int window_resize_callback(GtkWidget *w, GtkAllocation * size, gpointer data)
505 {
506 /*
507 g_message("x = %d, y = %d, width = %d, height = %d, data = %x\n",
508 size->x,size->y,size->width,size->height,data); */
509 context->set_value("h_size","int",(void*)size->width);
510 context->set_value("v_size","int",(void*)size->height);
511 return 0;
512 }
513
514 static void window_help_about_callback (GtkWidget *widget, gpointer data)
515 {
516 const gchar *authors[] = {"Xinkai Wang <aakwxk@hotmail.com>", NULL };
517 static GtkWidget *about_window = NULL;
518
519 if (!about_window)
520 {
521
522 GtkWidget *button;
523 GdkFont *font;
524
525 about_window = gtk_dialog_new ();
526 gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_MOUSE);
527 gtk_window_set_title (GTK_WINDOW (about_window), _("About gman"));
528
529 gtk_signal_connect (GTK_OBJECT (about_window), "delete_event",
530 GTK_SIGNAL_FUNC (gtk_false), NULL);
531 gtk_signal_connect (GTK_OBJECT (about_window), "destroy",
532 (GtkSignalFunc) gtk_widget_destroyed,
533 &about_window);
534
535 button = gtk_button_new_with_label (_("Close"));
536 gtk_widget_show (button);
537 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->action_area),
538 button, TRUE, TRUE, 0);
539 gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
540 (GtkSignalFunc) gtk_widget_destroy,
541 GTK_OBJECT (about_window));
542
543 gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (about_window)->vbox), 5);
544
545 /* TODO: we need a logo ;) */
546
547 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
548 gtk_label_new ("Gman - version " VERSION),
549 FALSE, FALSE, 5);
550
551 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
552 gtk_label_new ("Copyright (C) 1999 Xinkai Wang"),
553 FALSE, FALSE, 5);
554
555 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
556 gtk_label_new ("Comments and suggestions are extremely welcome!"),
557 FALSE, FALSE, 5);
558
559 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
560 gtk_label_new ("Web: http://homex.s-one.net.sg/user/xkwang/gman"),
561 FALSE, FALSE, 5);
562
563 if (!GTK_WIDGET_VISIBLE (about_window))
564 gtk_widget_show_all (about_window);
565 else
566 gtk_widget_hide (about_window);
567
568 }
569 }
570
571 static status_bar_callback (GtkWidget *widget, gpointer data)
572 {
573 int k,k2;
574 if(signal_menu_change>0) {signal_menu_change--;return 1;}
575 k2 = (int) context->get_value("show_status_bar");
576 k = (int) context->get_value("searching_mode");
577 if(((GtkCheckMenuItem*)(status_bar_button))->active) k2 = k2 | (1<<k);
578 else k2 = k2 & ~(1<<k);
579 pthread_mutex_lock(&context_lock);
580 context->set_value("show_status_bar","int",(void*)k2);
581 pthread_mutex_unlock(&context_lock);
582 updata_widget_show(0);
583 return 0;
584 }
585
586 static int search_mode_callback (GtkWidget *widget, gpointer data)
587 {
588 int k,k2;
589 k2 = (int) data;
590 if(!((GtkCheckMenuItem*)(searching_mode_buttons[k2]))->active) return 1;
591 if(signal_menu_change>0) {signal_menu_change--;return 1;}
592 //if(!signal) {signal++;return 1;}
593 //signal--;
594 k = (int) context->get_value("searching_mode");
595 if(k == k2) return 1;
596 pthread_mutex_lock(&context_lock);
597 context->set_value("searching_mode","int",(void*)k2);
598 pthread_mutex_unlock(&context_lock);
599 updata_widget_show(0);
600 updata_menu_buttons(0);
601 return 0;
602 }
603
604 static void entry4_activate_callback(GtkWidget *w,gpointer data)
605 {
606 keyword = gtk_entry_get_text(GTK_ENTRY(entry4));
607 task_set_active(task_key_word_search);
608 }
609
610 static void entry4_changed_callback(GtkWidget *w,gpointer data)
611 {
612 char * tmp;
613 tmp = gtk_entry_get_text(GTK_ENTRY(entry4));
614 gtk_widget_set_sensitive(search_button,strlen(tmp) >= 3);
615
616 }
617
618 static int button_clicked_callback(GtkWidget * w,gpointer data)
619 {
620 int i = (int) data;
621 switch (i) {
622 case 1: task_set_stop(task_key_word_search);break;
623 case 2: task_set_active(task_key_word_search);break;
624 }
625 }
0 /********************* menu.h *********************/
1
2 #ifndef _MENU_H
3 #define _MENU_H
4 #include "task.h"
5 #include <gtk/gtk.h>
6
7 void init_main_window(GtkWidget *);
8
9 extern GtkWidget * clist;
10 extern GtkWidget * clist3;
11
12 extern List * man_paths_to_be_load;
13 extern GtkTooltips * tooltips;
14 extern Dictionary * man_paths;
15 extern char * *man_items_buffer;
16 extern int man_items_count;
17 extern char *keyword;
18
19 extern GtkWidget *search_button;
20 extern GtkWidget *stop_button;
21
22 #endif
23
0 /* An alternative to qsort, with an identical interface.
1 This file is part of the GNU C Library.
2 Copyright (C) 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
3 Written by Mike Haertel, September 1988.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20 #include <stdlib.h>
21 #include <string.h>
22 #include <memcopy.h>
23 #include <errno.h>
24
25 static void msort_with_tmp __P ((void *b, size_t n, size_t s,
26 __compar_fn_t cmp, char *t));
27
28 static void
29 msort_with_tmp (b, n, s, cmp, t)
30 void *b;
31 size_t n;
32 size_t s;
33 __compar_fn_t cmp;
34 char *t;
35 {
36 char *tmp;
37 char *b1, *b2;
38 size_t n1, n2;
39
40 if (n <= 1)
41 return;
42
43 n1 = n / 2;
44 n2 = n - n1;
45 b1 = b;
46 b2 = (char *) b + (n1 * s);
47
48 msort_with_tmp (b1, n1, s, cmp, t);
49 msort_with_tmp (b2, n2, s, cmp, t);
50
51 tmp = t;
52
53 if (s == OPSIZ && (b1 - (char *) 0) % OPSIZ == 0)
54 /* We are operating on aligned words. Use direct word stores. */
55 while (n1 > 0 && n2 > 0)
56 {
57 if ((*cmp) (b1, b2) <= 0)
58 {
59 --n1;
60 *((op_t *) tmp)++ = *((op_t *) b1)++;
61 }
62 else
63 {
64 --n2;
65 *((op_t *) tmp)++ = *((op_t *) b2)++;
66 }
67 }
68 else
69 while (n1 > 0 && n2 > 0)
70 {
71 if ((*cmp) (b1, b2) <= 0)
72 {
73 tmp = (char *) __mempcpy (tmp, b1, s);
74 b1 += s;
75 --n1;
76 }
77 else
78 {
79 tmp = (char *) __mempcpy (tmp, b2, s);
80 b2 += s;
81 --n2;
82 }
83 }
84 if (n1 > 0)
85 memcpy (tmp, b1, n1 * s);
86 memcpy (b, t, (n - n2) * s);
87 }
88
89 void
90 qsort (b, n, s, cmp)
91 void *b;
92 size_t n;
93 size_t s;
94 __compar_fn_t cmp;
95 {
96 const size_t size = n * s;
97
98 if (size < 1024)
99 /* The temporary array is small, so put it on the stack. */
100 msort_with_tmp (b, n, s, cmp, __alloca (size));
101 else
102 {
103 /* It's somewhat large, so malloc it. */
104 int save = errno;
105 char *tmp = malloc (size);
106 if (tmp == NULL)
107 {
108 /* Couldn't get space, so use the slower algorithm
109 that doesn't need a temporary array. */
110 extern void _quicksort __P ((void *const __base,
111 size_t __nmemb, size_t __size,
112 __compar_fn_t __compar));
113 _quicksort (b, n, s, cmp);
114 }
115 else
116 {
117 msort_with_tmp (b, n, s, cmp, tmp);
118 free (tmp);
119 }
120 __set_errno (save);
121 }
122 }
+818
-0
t2.c less more
0 /********************** modified from myfont.c *******************/
1 /********************* to test the use of XmScrolledList *********/
2
3 #include <stdio.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #ifdef SYS_DIR
7 #include <sys_dir.h>
8 #else
9 #ifdef NDIR
10 #include <ndir.h>
11 #else
12 #include <dirent.h>
13 #endif
14 #endif
15
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <errno.h>
19
20 #include <stdlib.h>
21
22 #include <X11/Intrinsic.h>
23 #include <X11/IntrinsicP.h>
24 #include <X11/CoreP.h>
25 #include <X11/Shell.h>
26 #include <Xm/XmAll.h>
27
28 void main();
29 Widget MyCreateMain(Widget );
30 Widget SelectedFontSample(Widget );
31 Widget MyHelpDialog(Widget,int );
32
33 Widget slist;
34 Widget command_window;
35 //Widget swindow;
36 static int call_back_signal = 0;
37
38 void FontSelectedCB(Widget,caddr_t,caddr_t);
39 void CloseCB(Widget,caddr_t,caddr_t);
40 void HelpCB(Widget,int,caddr_t);
41 void QuitCB(Widget,caddr_t,caddr_t);
42 void ListSelectCB(Widget,caddr_t,XmListCallbackStruct *);
43 void ListActionCB(Widget,caddr_t,caddr_t);
44 void CommandWindowInputCB(Widget,caddr_t,caddr_t);
45 void MenuCommandCB(Widget,caddr_t,caddr_t);
46 void ActiveCB(Widget,caddr_t,caddr_t);
47
48 #define MAX_ARGS 20
49
50 #define MENU_DISPLAY_POSITION 201
51 #define MENU_NEXT_POSITION 202
52
53 typedef struct
54 {
55 char *fontpath;
56 }ApplicationData,*ApplicationDataPtr;
57
58 class ManPath;
59 class SubDir;
60 class ManItem;
61
62 class ManPath
63 {
64 public:
65 ManPath* next;
66 char * alias;
67 char * man_path;
68 SubDir* sub_dir[11];
69 public:
70 ManPath(char * path_name);
71 ~ManPath();
72 LoadManPath(char *);
73 int GetSize(char c);
74 int GetItems(char c, ManItem *buffer[]);
75 };
76
77 class SubDir
78 {
79 public:
80 ManPath *man_path;
81 int buffer_length;
82 int count;
83 ManItem **item_list;
84 public:
85 SubDir(ManPath *);
86 ~SubDir();
87 void AddItem(char* name);
88 int GetSize();
89 int GetItems(ManItem *buffer[]);
90 };
91
92 class ManItem
93 {
94 public:
95 SubDir *sub_dir;
96 char *name;
97 public:
98 ManItem(SubDir *, char* name);
99 ~ManItem();
100 };
101
102 void InitData();
103 static void attach (char *dest, const char *dirname, const char *name);
104 static int subdir_translate_c_to_n(char c);
105 static int ManItemComp(ManItem ** a,ManItem ** b);
106 static int ItemMatch(char *);
107 static void active_man_page(ManItem *);
108
109 ManPath * man_paths;
110 ManItem ** item_list;
111 int item_list_length;
112 int item_list_count;
113
114 ApplicationData AppData;
115
116 #define XtNfontPath "fontPath"
117 #define XtCFontPath "FontPath"
118 static XtResource resources[] =
119 {
120 {
121 XtNfontPath,XtCFontPath,XmRString,sizeof(String),
122 XtOffset(ApplicationDataPtr,fontpath),
123 //XmRString,"/usr/lib/X11/fonts/misc"
124 XmRString,"/home/wxk/fonts"
125 }
126 };
127
128 static XmStringCharSet charset = (XmStringCharSet)XmSTRING_DEFAULT_CHARSET;
129
130 /********************** main **********************/
131 void main(int argc,char ** argv)
132 {
133 Widget toplevel;
134 Widget main_window;
135 XtAppContext app_context;
136
137 toplevel = XtVaAppInitialize(&app_context,"XMdemos",NULL,0,
138 &argc,argv,NULL,XmNallowShellResize,True,NULL);
139 main_window = MyCreateMain(toplevel);
140 XtRealizeWidget(toplevel);
141
142 XtAppMainLoop(app_context);
143 }
144
145 /********************* MyCreateMain *************************/
146 Widget MyCreateMain(Widget parent)
147 {
148 Widget main_window;
149 Widget menu_bar;
150 Widget menu_pane;
151 Widget cascade;
152 Widget frame;
153 Widget form;
154 Widget button;
155 Widget hsb,vsb;
156
157 Arg args[MAX_ARGS];
158 register int n;
159 DIR *dirp;
160 #if defined(SYS_DIR)||defined(NDIR)
161 struct direct *item;
162 #else
163 struct dirent *item;
164 #endif
165
166 char filename[80];
167 int len;
168 int i,j,k;
169 XmString label_string;
170 XmString stringx[2];
171
172 /***************** Init Data *************/
173 InitData();
174
175 printf("piont3.0\n");
176 /***************** Create MainWindow *************/
177 n = 0;
178 main_window = XmCreateMainWindow(parent,"main1",args,n);
179 XtManageChild(main_window);
180
181 /***************** Create MenuBar ***************/
182 n = 0;
183 menu_bar = XmCreateMenuBar(main_window,"menu_bar",args,n);
184 XtManageChild(menu_bar);
185 XmAddTabGroup(menu_bar);
186
187 /***************** Create "exit" menu ************/
188 n = 0;
189 menu_pane = XmCreatePulldownMenu(menu_bar,"menu_pane",args,n);
190
191 n = 0;
192 button = XmCreatePushButton(menu_pane,"Quit",args,n);
193 XtManageChild(button);
194 XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))QuitCB,(XtPointer)NULL);
195
196 n = 0;
197 button = XmCreatePushButton(menu_pane,"Display",args,n);
198 XtManageChild(button);
199 XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))MenuCommandCB,(XtPointer)MENU_DISPLAY_POSITION);
200
201 n = 0;
202 button = XmCreatePushButton(menu_pane,"Next",args,n);
203 XtManageChild(button);
204 XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))MenuCommandCB,(XtPointer)MENU_NEXT_POSITION);
205
206 printf("piont3.2\n");
207 n = 0;
208 XtSetArg(args[n],XmNsubMenuId,menu_pane);n++;
209 cascade = XmCreateCascadeButton(menu_bar,"Exit",args,n);
210 XtManageChild(cascade);
211
212 /***************** Create "help" menu ************/
213 n = 0;
214 //cascade = XmCreateCascadeButton(menu_bar,"help",args,n);
215 cascade = XmCreateCascadeButtonGadget(menu_bar,"help",args,n);
216 XtManageChild(cascade);
217 XtAddCallback(cascade,XmNactivateCallback,(void (*)(Widget,void *, void *))HelpCB,(XtPointer)1);
218
219 n = 0;
220 XtSetArg(args[n],XmNmenuHelpWidget,cascade);n++;
221 XtSetValues(menu_bar,args,n);
222
223 /***************** Create Frame window ********/
224 n = 0;
225 XtSetArg(args[n],XmNmarginWidth,2);n++;
226 XtSetArg(args[n],XmNmarginHeight,2);n++;
227 XtSetArg(args[n],XmNshadowThickness,1);n++;
228 XtSetArg(args[n],XmNshadowType,XmSHADOW_OUT);n++;
229 frame = XmCreateFrame(main_window,"frame",args,n);
230 XtManageChild(frame);
231
232 /***************** Create command window ********/
233 n = 0;
234 form = XmCreateForm(frame,"form",args,n);
235 XtManageChild(form);
236 n = 0;
237 XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM);n++;
238 XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM);n++;
239 XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM);n++;
240 command_window = XmCreateTextField(form,"textfield",args,n);
241 XtManageChild(command_window);
242
243 /***************** Create Scrolled list ***************/
244 n = 0;
245 XtSetArg(args[n],XmNtopAttachment,XmATTACH_WIDGET);n++;
246 XtSetArg(args[n],XmNtopWidget,command_window);n++;
247 XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM);n++;
248 XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM);n++;
249 XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM);n++;
250 XtSetArg(args[n],XmNscrollBarDisplayPolicy,XmAS_NEEDED);n++;
251 XtSetArg(args[n],XmNscrollingPolicy,XmAUTOMATIC);n++;
252 XtSetArg(args[n],XmNvisibleItemCount,30);n++;
253 XtSetArg(args[n],XmNlistMarginWidth,5);n++;
254 XtSetArg(args[n],XmNwidth,400);n++;
255 XtSetArg(args[n],XmNlistSizePolicy,XmCONSTANT);n++;
256 slist = XmCreateScrolledList(form,"slist",args,n);
257 XtManageChild(slist);
258
259 /**************** Set MainWindow areas and add tab groups *******
260 XmMainWindowSetAreas(main_window,menu_bar,NULL,NULL,NULL,frame);
261 n = 0;
262 XtSetArg(args[n],XmNhorizontalScrollBar,&hsb);n++;
263 XtSetArg(args[n],XmNverticalScrollBar,&vsb);n++;
264 XtGetValues(swindow,args,n);
265 XmAddTabGroup(slist);
266 printf("hsb = %x, vsb = %x",hsb,vsb);
267 if(hsb) XmAddTabGroup(hsb);
268 if(vsb) XmAddTabGroup(vsb);
269 */
270 XmAddTabGroup(slist);
271 XmAddTabGroup(command_window);
272
273 //system("ls /home/wxk/x ");
274 /**************** Create items in the slist **********/
275 for (i=0;i<item_list_count;i++)
276 {
277 label_string = XmStringCreateLtoR(item_list[i]->name,charset);
278 XmListAddItem(slist,label_string,0);
279 //if (!strcmp(filename,"core")) stringx[0] = label_string;
280 XmStringFree(label_string);
281 }
282 n = 0;
283 //XtSetArg(args[n],XmNselectedItemCount,1);n++;
284 //XtSetArg(args[n],XmNselectedItems,stringx);n++;
285 //XtSetArg(args[n],XmNtopItemPosition,14);n++;
286 XtSetValues(slist,args,n);
287 XtAddCallback(slist,XmNbrowseSelectionCallback,(void (*)(Widget,void *, void *))ListSelectCB,(XtPointer)NULL);
288 XtAddCallback(slist,XmNdefaultActionCallback,(void (*)(Widget,void *, void *))ActiveCB,(XtPointer)NULL);
289 XtAddCallback(command_window,XmNvalueChangedCallback,(void (*)(Widget,void *, void *))CommandWindowInputCB,(XtPointer)NULL);
290 XtAddCallback(command_window,XmNactivateCallback,(void (*)(Widget,void *, void *))ActiveCB,(XtPointer)NULL);
291 printf("piont3.10\n");
292 return(main_window);
293 }
294
295 /********************* SelectFontCB ***********************/
296 Widget SelectedFontSample(Widget widget)
297 {
298 Widget message_box;
299 Widget button;
300 Arg args[MAX_ARGS];
301 register int n;
302 int i;
303 XtPointer * buffer;
304 char *name = NULL;
305 XFontStruct * font = NULL;
306 XmFontList fontlist = NULL;
307 static char message[BUFSIZ];
308 XmString name_string = NULL;
309 XmString message_string = NULL;
310 XmString button_string = NULL;
311
312 /******************* get font name *********************/
313 printf("piont SelectedFontSample\n");
314 XtVaGetValues(widget,XmNlabelString,&name_string,NULL);
315 XmStringGetLtoR(name_string,charset,&name);
316 /*
317 for(i=0;i<10;i++)
318 {
319 if(name) font = XLoadQueryFont(XtDisplay(XtParent(widget)),name);
320 if(font == NULL) sprintf(message,"Unable to load font:%s.",name);
321 else
322 {
323 fontlist = XmFontListCreate(font,charset);
324 sprintf(message,"\n This is font %s.\n The quick brown fox jumps over the lazy dog.",name);
325 }
326 printf("font=%x, fontlist=%x\n",font,fontlist);
327 XmFontListFree(fontlist);
328 if(font) XFreeFont(XtDisplay(XtParent(widget)),font);
329 }
330 */
331 if(name) font = XLoadQueryFont(XtDisplay(XtParent(widget)),name);
332 if(font == NULL) sprintf(message,"Unable to load font:%s.",name);
333 else
334 {
335 fontlist = XmFontListCreate(font,charset);
336 sprintf(message,"\n This is font %s.\n The quick brown fox jumps over the lazy dog.",name);
337 }
338 printf("font=%x, fontlist=%x\n",font,fontlist);
339 buffer = (XtPointer*)XtMalloc(sizeof(XtPointer)*2);
340 printf("buffer=%x, size=%d\n",buffer,sizeof(XtPointer)*2);
341 buffer[0] = (XtPointer)fontlist;
342 buffer[1] = (XtPointer)font;
343
344 printf("piont SelectedFontSample, name=%x, name_string=%x, font=%x\n",name,name_string,font);
345 message_string = XmStringCreateLtoR(message,charset);
346 for(i=0;i<0;i++)
347 {
348 button_string = XmStringCreateLtoR("Close",charset);
349 printf("button_string=%x\n",button_string);
350 XmStringFree(button_string);
351 }
352 button_string = XmStringCreateLtoR("Close",charset);
353
354 n = 0;
355 if (fontlist)
356 {
357 XtSetArg(args[n],XmNlabelFontList,fontlist);n++;
358 }
359 XtSetArg(args[n],XmNdialogTitle,name_string);n++;
360 XtSetArg(args[n],XmNokLabelString,button_string);n++;
361 XtSetArg(args[n],XmNmessageString,message_string);n++;
362 for(i=0;i<0;i++)
363 {
364 message_box = XmCreateMessageDialog(XtParent(XtParent(widget)),"fontbox",args,n);
365 XtDestroyWidget(message_box);
366 }
367 message_box = XmCreateMessageDialog(XtParent(XtParent(widget)),"fontbox",args,n);
368 XtAddCallback(message_box,XmNokCallback,(void (*)(Widget,void *, void *))CloseCB,(XtPointer)buffer);
369 XtAddCallback(message_box,XmNhelpCallback,(void (*)(Widget,void *, void *))HelpCB,(XtPointer)2);
370
371 button = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON);
372 //if(name_string) XmStringFree(name_string);
373 //XtVaGetValues(button,XmNlabelString,&name_string,NULL);
374 //if(name_string) XmStringFree(name_string);
375 XtUnmanageChild(button);
376 //XtDestroyWidget(button);
377
378 //if(fontlist) XmFontListFree(fontlist);
379 if(name) XtFree((char*)name);
380 //if(name_string) XtFree((char*)name_string);
381 //if(message_string) XtFree((char*)message_string);
382 //if(button_string) XtFree((char*)button_string);
383 if(button_string) XmStringFree(button_string);
384 if(message_string) XmStringFree(message_string);
385 printf("button_string=%x, message_string=%x, name_string=%x\n",button_string,message_string,name_string);
386 return (message_box);
387 }
388
389 Widget MyHelpDialog(Widget parent,int flag)
390 {
391 static int first_time = 1;
392 static Widget message_box;
393 Arg args[MAX_ARGS];
394 register int n;
395
396 static char message[BUFSIZ];
397 XmString title_string = NULL;
398 static XmString message_string1 = NULL;
399 static XmString message_string2 = NULL;
400 XmString button_string = NULL;
401
402 if (first_time)
403 {
404 Widget wtmp;
405 n = 0;
406 message_box = XmCreateMessageDialog(XtParent(XtParent(parent)),"helpbox",args,n);
407 button_string = XmStringCreateLtoR("Close",charset);
408 title_string = XmStringCreateLtoR("myfonts help",charset);
409 message_string1 = XmStringCreateLtoR("\nPush one button to get the sample "
410 "\ntext display in the font.\n(Some font may not be opened.)",charset);
411 message_string2 = XmStringCreateLtoR("\n The help text for this specific font.\n",charset);
412
413 XtVaSetValues(message_box,XmNdialogTitle,title_string,XmNokLabelString,button_string,NULL);
414 wtmp = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON);
415 XtUnmanageChild(wtmp);
416 wtmp = XmMessageBoxGetChild(message_box,XmDIALOG_HELP_BUTTON);
417 XtUnmanageChild(wtmp);
418 first_time = 0;
419 }
420
421 if (flag == 1)
422 XtVaSetValues(message_box,XmNmessageString,message_string1,NULL);
423 else
424 XtVaSetValues(message_box,XmNmessageString,message_string2,NULL);
425
426 return (message_box);
427 }
428
429 void FontSelectedCB(Widget w,caddr_t client_data,caddr_t call_data)
430 {
431 Widget message_box;
432 //putchar(007);fflush(stdout);
433 message_box = SelectedFontSample(w);
434 XtManageChild(message_box);
435 }
436
437 void CloseCB(Widget w,caddr_t client_data,caddr_t call_data)
438 {
439 XmString message_string = NULL;
440 XmString button_string = NULL;
441 XmString name_string = NULL;
442 Widget button;
443 XtPointer * buffer;
444
445 Widget message_box = XtParent(w);
446 buffer = (XtPointer*)client_data;
447 printf("buffer=%x, call_data=%x\n",buffer,call_data);
448 //putchar(007);fflush(stdout);
449 //XtVaGetValues(w,XmNokLabelString,&button_string,XmNmessageString,&message_string,XmNdialogTitle,&name_string,NULL);
450 //printf("freeing button_string=%x, message_string=%x\n",button_string,message_string);
451 XtUnmanageChild(message_box);
452 XtDestroyWidget(message_box);
453
454 if(buffer[0]) XmFontListFree((XmFontList)buffer[0]);
455 //printf("font=%x, fontlist=%x\n",buffer[1],buffer[0]);
456 if(buffer[1]) XFreeFont(XtDisplay(XtParent(w)),(XFontStruct *)buffer[1]);
457 XtFree((char*)buffer);
458 /*
459 if(button_string) XmStringFree(button_string);
460 if(button_string) XmStringFree(button_string);
461 if(message_string) XmStringFree(message_string);
462 if(message_string) XmStringFree(message_string);
463 */
464 }
465
466 void HelpCB(Widget w,int tag,caddr_t call_data)
467 {
468 Widget message_box;
469 int i = tag;
470 printf("tag=%d\n",tag);
471 //putchar(007);fflush(stdout);
472 message_box = MyHelpDialog(w,i);
473 XtManageChild(message_box);
474 }
475
476 void QuitCB(Widget w,caddr_t client_data,caddr_t call_data)
477 {
478 //putchar(007);fflush(stdout);
479 exit(0);
480 }
481
482 void MenuCommandCB(Widget w,caddr_t client_data,caddr_t call_data)
483 {
484 Arg args[MAX_ARGS];
485 int command;
486 int n;
487 int *position;
488 int buffer[4];
489
490 command = (int)client_data;
491 switch(command)
492 {
493 case MENU_DISPLAY_POSITION:
494 n = 0;
495 XtSetArg(args[n],XmNselectedPositions,&position);n++;
496 XtGetValues(slist,args,n);
497 if(position) printf("MenuCommandCB: position[0] = %d\n",*position);
498 else printf("MenuCommandCB: position = NULL\n");
499 break;
500 case MENU_NEXT_POSITION:
501 n = 0;
502 XtSetArg(args[n],XmNselectedPositions,&position);n++;
503 XtGetValues(slist,args,n);
504 if(position)
505 {
506 buffer[0] = *position + 1;
507 XmListDeselectAllItems(slist);
508 n = 0;
509 XtSetArg(args[n],XmNselectedPositions,buffer);n++;
510 XtSetArg(args[n],XmNselectedPositionCount,1);n++;
511 XtSetValues(slist,args,n);
512 }
513 else
514 {
515 buffer[0] = 10;
516 n = 0;
517 XtSetArg(args[n],XmNselectedPositions,buffer);n++;
518 XtSetArg(args[n],XmNselectedPositionCount,1);n++;
519 XtSetValues(slist,args,n);
520 }
521 break;
522 default:
523 printf("undefined command\n");
524 }
525 }
526
527 void ListSelectCB(Widget w,caddr_t client_data,XmListCallbackStruct * callback_data)
528 {
529 Arg args[MAX_ARGS];
530 int n;
531 int *position;
532
533 n = 0;
534 XtSetArg(args[n],XmNselectedPositions,&position);n++;
535 XtGetValues(slist,args,n);
536 //printf("ListSelectCB: position = %d\n",*position);
537 //n = 0;
538 //XtSetArg(args[n],XmNtopItemPosition,(*position-1)?(*position-1):1);n++;
539 //XtSetValues(slist,args,n);
540 call_back_signal = 1;
541 XmTextSetString(command_window,item_list[*position-1]->name);
542 }
543
544 void ActiveCB(Widget w,caddr_t client_data,caddr_t call_data)
545 {
546 Arg args[MAX_ARGS];
547 int n;
548 int *position;
549
550 n = 0;
551 XtSetArg(args[n],XmNselectedPositions,&position);n++;
552 XtGetValues(slist,args,n);
553 if(!position) return;
554 //printf("active = %d, name = %s\n",position[0]-1,item_list[position[0]-1]->name);
555 active_man_page(item_list[position[0]-1]);
556 }
557
558 void CommandWindowInputCB(Widget w,caddr_t client_data,caddr_t call_data)
559 {
560 Arg args[MAX_ARGS];
561 int n;
562 int count;
563 char * name;
564 int position;
565 int *positions;
566
567 if (call_back_signal)
568 {
569 call_back_signal = 0;
570 return;
571 }
572
573 name = XmTextGetString(command_window);
574
575 position = ItemMatch(name);
576 position ++;
577 //printf("match position = %d\n",position);
578 XtFree(name);
579
580 XmListDeselectAllItems(slist);
581 n = 0;
582 XtSetArg(args[n],XmNselectedPositionCount,1);n++;
583 XtSetArg(args[n],XmNselectedPositions,&position);n++;
584 XtSetArg(args[n],XmNtopItemPosition,(position-1)?(position-1):1);n++;
585 XtSetValues(slist,args,n);
586 }
587
588 /************************* ManPath ************************/
589 ManPath::ManPath(char* path_name)
590 {
591 int i;
592 int len;
593 next = NULL;
594 alias = NULL;
595 len = strlen(path_name);
596 man_path = (char*)malloc(len+1);
597 strncpy(man_path,path_name,len);
598 man_path[len] = '\0';
599 for (i=0;i<11;i++) sub_dir[i] = new SubDir(this);
600 LoadManPath(path_name);
601 }
602
603 ManPath::~ManPath()
604 {
605 int i;
606 for (i = 0;i<11;i++) delete(sub_dir[i]);
607 free(man_path);
608 }
609
610 ManPath::GetSize(char c)
611 {
612 int count;
613 int i;
614 int type = subdir_translate_c_to_n(c)+1;
615 if (type <= 11 && type >= 1) return sub_dir[type-1]->GetSize();
616 for (i = count = 0;i<11;i++) count += sub_dir[i]->GetSize();
617 return count;
618 }
619
620 ManPath::GetItems(char c, ManItem * buffer[])
621 {
622 int count;
623 int i;
624 int type = subdir_translate_c_to_n(c)+1;
625 if (type <= 11 && type >= 1) return sub_dir[type-1]->GetItems(buffer);
626 for (i = count = 0;i<11;i++) count += sub_dir[i]->GetItems(buffer+count);
627 return count;
628 }
629
630 struct stat state;
631
632 ManPath::LoadManPath(char * path_name)
633 {
634 DIR *dirp;
635 #if defined(SYS_DIR)||defined(NDIR)
636 struct direct *item;
637 #else
638 struct dirent *item;
639 #endif
640
641 int len;
642 int val;
643 char name[180];
644
645 man_path = (char*)realloc(man_path,strlen(path_name)+1);
646 strcpy(man_path,path_name);
647
648 dirp = opendir(path_name);
649 if (!dirp)
650 {
651 fprintf(stderr,"Can not open man path %s\n",path_name);
652 }
653 for (item = readdir(dirp);item != NULL;item = readdir(dirp))
654 {
655 if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0)))
656 continue;
657 attach(name,path_name,item->d_name);
658 val = stat (name, &state);
659 if (val < 0) fprintf(stderr,"error number %d, in get state %s",errno,name);
660 else if (S_ISDIR(state.st_mode)) LoadManPath(name);
661 else
662 {
663 len = (strlen(item -> d_name));
664 if(item -> d_name[len-2] == '.')
665 {
666 val = subdir_translate_c_to_n(item->d_name[len-1]);
667 strncpy(name,item->d_name,len-2);
668 name[len-2] = '(';
669 name[len-1] = item->d_name[len-1];
670 name[len] = ')';
671 name[len+1] = '\0';
672 sub_dir[val]->AddItem(name);
673 }
674 else if(item -> d_name[len-3] == '.')
675 {
676 val = subdir_translate_c_to_n(item->d_name[len-2]);
677 strncpy(name,item->d_name,len-3);
678 name[len-3] = '(';
679 name[len-2] = item->d_name[len-2];
680 name[len-1] = item->d_name[len-1];
681 name[len] = ')';
682 name[len+1] = '\0';
683 sub_dir[val]->AddItem(name);
684 }
685 }
686 }
687 }
688
689 /************************* SubDir ************************/
690 SubDir::SubDir(ManPath* path)
691 {
692 man_path = path;
693 buffer_length = 64;
694 count = 0;
695 item_list = (ManItem**)malloc(buffer_length*sizeof(ManItem*));
696 }
697
698 SubDir::~SubDir()
699 {
700 int i;
701 for (i=0;i<count;i++) delete(item_list[i]);
702 free(item_list);
703 }
704
705 void SubDir::AddItem(char * file_name)
706 {
707 if(count >= buffer_length) item_list = (ManItem**)realloc(item_list,(buffer_length*=2)*sizeof(*item_list));
708 item_list[count++] = new ManItem(this,file_name);
709 }
710
711 inline SubDir::GetSize()
712 {
713 return count;
714 }
715
716 SubDir::GetItems(ManItem *buffer[])
717 {
718 memcpy(buffer,item_list,count*sizeof(ManItem*));
719 return count;
720 }
721
722 /************************* ManItem ************************/
723 inline ManItem::ManItem(SubDir * sub,char *name)
724 {
725 int len;
726 len = strlen(name);
727 this->name = (char*)malloc(len+1);
728 strncpy(this->name,name,len);
729 this->name[len] = '\0';
730 }
731
732 inline ManItem::~ManItem()
733 {
734 free(name);
735 }
736
737 /************************* init global data ************************/
738 void InitData()
739 {
740 int i;
741 man_paths = NULL;
742 item_list = NULL;
743 item_list_length = 0;
744 item_list_count = 0;
745
746 man_paths = new ManPath("/usr/X11/man/");
747 printf("GetSize = %d\n",man_paths->GetSize('a'));
748
749 item_list_length = item_list_count = man_paths->GetSize('a');
750 printf("GetSize = %d\n",item_list_count);
751 item_list = (ManItem**)malloc(item_list_count*sizeof(ManItem*));
752 man_paths->GetItems('a',item_list);
753 qsort(item_list,item_list_count,sizeof(ManItem*),&ManItemComp);
754 //for(i=0;i<item_list_count;i++) printf("%s\n",item_list[i]->name);
755 }
756
757 /* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */
758
759 static void attach (char *dest, const char *dirname, const char *name)
760 {
761 const char *dirnamep = dirname;
762
763 /* Copy dirname if it is not ".". */
764 if (dirname[0] != '.' || dirname[1] != 0)
765 {
766 while (*dirnamep) *dest++ = *dirnamep++;
767 /* Add '/' if `dirname' doesn't already end with it. */
768 if (dirnamep > dirname && dirnamep[-1] != '/') *dest++ = '/';
769 }
770 while (*name) *dest++ = *name++;
771 *dest = 0;
772 }
773
774 int subdir_translate_c_to_n(char c)
775 {
776 if(c<='8' && c>='1') return (c-'1');
777 else if(c == 'n') return 8;
778 else if(c == 'l') return 9;
779 else if(c == 'a') return -1;
780 else return 10;
781 }
782
783 int ManItemComp(ManItem ** a,ManItem ** b)
784 {
785 return (strcmp((*a)->name,(*b)->name));
786 }
787
788 int ItemMatch(char * name)
789 {
790 int i;
791 for (i=0;i<item_list_count && strcmp(name,item_list[i]->name)>0 ;i++);
792 return (i >= item_list_count)? i-1:i;
793 }
794
795 static void active_man_page(ManItem * item)
796 {
797 int i;
798 int len,len2;
799 char buffer[180];
800 len = strlen(item->name);
801 if (item->name[len-3] == '(') len -= 3;
802 else len -= 4;
803
804 strcpy(buffer,"nxterm -T '");
805 strcat(buffer,item->name);
806 strcat(buffer,"' -n KMan -e man ");
807 len2 = strlen(buffer);
808 strncat(buffer,item->name,len); buffer[len+len2] = '\0';
809 if(!fork())
810 {
811 //printf(buffer);
812 system(buffer);
813 exit(0);
814 }
815 return;
816 }
817
0 /************************ task.c ***************************/
1 /*********************** 1999.6.21 *************************/
2
3 #include "task.h"
4 #include <stdio.h>
5 #include <unistd.h>
6 #include <pthread.h>
7
8 struct _task_group {
9 pthread_t thread;
10 pthread_attr_t attr;
11 pthread_mutex_t lock;
12 int state;
13 List * tasks;
14 };
15
16 struct _task {
17 TaskGroup * task_group;
18 pthread_mutex_t lock;
19 int state;
20 float priority;
21 TaskRunFunc task_run_func;
22 gpointer user_data;
23 List * signals[2];
24 //signal quenes, 1 for synchronous signals, 0 for unsynchronous signals
25 };
26
27 static void * task_group_running(TaskGroup *);
28 static void task_group_set_active(TaskGroup *);
29
30 TaskGroup * task_group_new()
31 {
32 int retcode;
33 TaskGroup * task_group = (TaskGroup*)g_malloc(sizeof(TaskGroup));
34 task_group->tasks = new List;
35 task_group->state = 0;
36 pthread_attr_init(&(task_group->attr));
37 pthread_attr_setdetachstate(&(task_group->attr), 1);
38 pthread_mutex_init(&task_group->lock,NULL);
39 //retcode = pthread_create(&task_group->thread, NULL, (void*(*)(void*))my_thread_running, (void *) task_group);
40 //if (retcode != 0) g_error("my_thread_new:thread creation failed %d\n", retcode);
41 return task_group;
42 }
43
44 Task * task_new(TaskGroup * task_group, float priority, TaskRunFunc task_func, gpointer data)
45 {
46 int i,j,k;
47 Task * task;
48 g_return_val_if_fail((priority>0.0 && priority <1.0)&&(task_group != NULL)&&(task_func != NULL),NULL);
49
50 task = (Task *)g_malloc(sizeof(Task));
51 pthread_mutex_init(&task->lock,NULL);
52 task->priority = priority;
53 task->state = 0;
54 task->task_group = task_group;
55 task->task_run_func = task_func;
56 task->user_data = data;
57 task->signals[0] = new List;
58 task->signals[1] = new List;
59
60 pthread_mutex_lock(&task_group->lock);
61 j = task_group->tasks->get_size();
62 for(i = 0;i<j && priority>((Task*)task_group->tasks->get_item(i))->priority;i++);
63 task_group->tasks->insert_item(i,(void*)task);
64 pthread_mutex_unlock(&task_group->lock);
65
66 return task;
67 }
68
69 void task_signal_send(Task * task, int signal)
70 {
71 g_return_if_fail(task != NULL);
72 pthread_mutex_lock(&task->lock);
73 task->signals[signal&1]->add_item((void*)signal);
74 pthread_mutex_unlock(&task->lock);
75 task_group_set_active(task->task_group);
76 }
77
78 void task_set_active(Task * task)
79 {
80 task_signal_send(task,TASK_START);
81 }
82
83 void task_set_stop(Task * task)
84 {
85 task_signal_send(task,TASK_STOP);
86 }
87
88 //let the task itself to decide wether to stop or not
89 //of the task don't want to be wake up any more, it will return 0,
90 //otherwise 1.
91
92 static void task_group_set_active(TaskGroup * task_group)
93 {
94 int retcode;
95 pthread_mutex_lock(&task_group->lock);
96 if(!task_group->state) {
97 task_group->state |= 1;
98 retcode = pthread_create(&task_group->thread, &task_group->attr, (void*(*)(void*))task_group_running, (void *) task_group);
99 if (retcode != 0) g_error("thread creation failed %d\n", retcode);
100 }
101 pthread_mutex_unlock(&task_group->lock);
102 }
103
104 static void * task_group_running(TaskGroup * task_group)
105 {
106 int i,j;
107 int have_task;
108 int state,k;
109 Task * task;
110
111 do {
112 have_task = 0;
113 task = NULL;
114 int flag;
115 pthread_mutex_lock(&task_group->lock);
116 j = task_group->tasks->get_size();
117 for(i = 0; i<j && !have_task ;i++) {
118 if((task = (Task*)task_group->tasks->get_item(i))->signals[0]->get_size()) {
119 flag = ((int)task->signals[0]->get_item(0) & ~1) | (task->state & 1);
120 task->signals[0]->delete_item(0);
121 have_task++;
122 }
123 else if (task->state & TASK_RUNNING) {
124 flag = task->state & TASK_RUNNING;
125 have_task++;
126 }
127 else if (task->signals[1]->get_size()) {
128 flag = ((int)task->signals[1]->get_item(1) & ~1);
129 task->signals[1]->delete_item(0);
130 have_task++;
131 }
132 }
133 pthread_mutex_unlock(&task_group->lock);
134 if(have_task) {
135 // printf("init state = %x\n",task->state);
136 state = (*task->task_run_func)(flag,task->user_data);
137 if(state)
138 task->state |= TASK_RUNNING;
139 else
140 task->state &= ~TASK_RUNNING;
141 // printf("return state = %x\n",task->state);
142 }
143 } while (have_task);
144 pthread_mutex_lock(&task_group->lock);
145 task_group->state &= ~TASK_RUNNING;
146 pthread_mutex_unlock(&task_group->lock);
147 return 0;
148 }
149
0 /************************ task.h ***************************/
1 /************************ 1999.6.21 ************************/
2
3 #ifndef _TASK_H
4 #define _TASK_H
5
6 #include <glib.h>
7 #include "list.h"
8
9 typedef enum
10 {
11 TASK_RUNNING = 1 << 0,
12 TASK_START = 1 << 1,
13 TASK_STOP = 1 << 2,
14 } MyTaskRunningFlags;
15
16 typedef struct _task_group TaskGroup;
17 typedef struct _task Task;
18 typedef int (* TaskRunFunc) (int flag, gpointer data);
19
20 TaskGroup * task_group_new();
21 Task * task_new(TaskGroup * thread, float priority, TaskRunFunc task_func, gpointer data);
22 void task_signal_send(Task * task, int signal);
23 void task_set_active(Task * task);
24 void task_set_stop(Task * task);
25
26 #endif
27
0 #include <stdlib.h>
1 #include "taskfunc.h"
2 #include "menu.h"
3 #include "mandata.h"
4 #include "context.h"
5 #include "util.h"
6 #include "gman.h"
7 #include <string.h>
8 #include "window2.h"
9 #include <unistd.h>
10 #include <sys/types.h>
11 #include <signal.h>
12 #include <errno.h>
13 #include <stdio.h>
14
15 //#include <gtk/gtk.h>
16
17 /********************* init_man_data *************************/
18 int init_man_data()
19 {
20 ManPath * path;
21 char * path_name,*p1,*p2;
22 int end = 0;
23 man_paths = new Dictionary;
24 path_name = my_strdup((char*)context->get_value("man_paths"));
25 p1 = path_name;
26 while(!end) {
27 p2 = strchr(p1,(int)':');
28 if(p2 == NULL) end++;
29 else *p2 = '\0';
30 man_paths->add_item(my_strdup(p1),(void*)( new ManPath(p1)));
31 p1 = p2+1;
32 }
33 if(path_name) free (path_name);
34 return 0;
35 }
36
37 int extract_man_data()
38 {
39 ManItem ** buffer;
40 int i,j,count;
41 int display_section_ID;
42
43 pthread_mutex_lock(&context_lock);
44 switch ((int)context->get_value("display_section_policy")) {
45 case 0: display_section_ID = ~0;break;
46 case 1: display_section_ID = ~(int)(context->get_value("display_section"));break;
47 case 2: display_section_ID = (int)context->get_value("display_section"); break;
48 default: fprintf(stderr,"warning: init_man_data: \"display_section_policy\" "
49 "have invalid value %d",context->get_value("display_section_policy"));
50 display_section_ID = ~0;
51 }
52 pthread_mutex_unlock(&context_lock);
53
54 if(man_items_count) free(man_items_buffer);
55 j = man_paths->get_size();
56 for(i = man_items_count = 0;i<j;i++)
57 man_items_count += ((ManPath*)(man_paths->get_value(i)))->GetSize(display_section_ID);
58 buffer = (ManItem**)malloc(sizeof(ManItem*)*man_items_count);
59 man_items_buffer = (char**) buffer;
60 for(i = count = 0;i<j;i++)
61 count += ((ManPath*)(man_paths->get_value(i)))->GetItems(display_section_ID,buffer+count);
62 if( count != man_items_count) exit(1);
63
64 if(context->get_value("debuging")) printf("count = %d\n",count);
65 qsort((void *)buffer,count,sizeof(ManItem*),(int(*)(const void*,const void*))&man_item_compare);
66 if(context->get_value("debuging")) printf("count = %d, qsort end.\n",count);
67
68 return 0;
69 }
70
71 int add_data_to_clist(int flag)
72 {
73 gchar *text[2];
74 static int i;
75 int j,k;
76 ManItem ** buffer;
77 static char ** pointer;
78 char a[100],b[20];
79 int display_section_ID;
80
81 text[0] = a; text[1] = b;
82 buffer = (ManItem**) man_items_buffer;
83
84 pthread_mutex_lock(&gtk_lock);
85
86 if(flag & TASK_START) {
87 i = 0;
88 pointer = man_items_buffer;
89 gtk_clist_clear(GTK_CLIST(clist));
90 }
91
92 gtk_clist_freeze(GTK_CLIST(clist));
93 for (j = 0;j<100 & i< man_items_count;i++,j++) {
94 buffer[i]->get_display_name(a);
95 buffer[i]->get_section_name(b);
96 gtk_clist_append(GTK_CLIST(clist),text);
97 gtk_clist_set_row_data(GTK_CLIST(clist),i,(gpointer)buffer[i]);
98 gtk_clist_get_text(GTK_CLIST(clist),i,0,pointer++);
99 }
100 gtk_clist_thaw(GTK_CLIST(clist));
101 pthread_mutex_unlock(&gtk_lock);
102
103 //pointer = man_items_display_name;
104 //for(int i = 0;i<man_items_count;i++) printf(*(pointer++));
105 return (i < man_items_count);
106 }
107
108 int loading_man_data()
109 {
110 ManPath * p;
111 char * c;
112 int i;
113 char buffer[100];
114 if(!man_paths_to_be_load->get_size()) return 0;
115 pthread_mutex_lock(&loading_man_path_lock);
116 c = (char*)man_paths_to_be_load->get_item(0);
117 man_paths_to_be_load->delete_item(0);
118 pthread_mutex_unlock(&loading_man_path_lock);
119 p = new ManPath(c);
120 i = man_paths->search_item(c);
121 if (i == -1) {
122 delete (p);
123 g_warning("man path %s does not exist\n",c);
124 return man_paths_to_be_load->get_size();
125 }
126 // printf("loading... %d end\n",i);
127 man_paths->set_value(i,(void*)p);
128 if(clist2) {
129 sprintf(buffer,"%d",p->GetSize(-1));
130 pthread_mutex_lock(&gtk_lock);
131 gtk_clist_set_text(GTK_CLIST(clist2),i,2,buffer);
132 pthread_mutex_unlock(&gtk_lock);
133 }
134 return man_paths_to_be_load->get_size();
135 }
136
137 int is_blank(char c) {return (c==0x20||c==0x09)?1:0;}
138
139 typedef enum
140 {
141 S_START,
142 S_NAME,
143 S_NAME_END1,
144 S_NAME_END2,
145 S_SECTION,
146 S_SECTION_END1,
147 S_SECTION_END2,
148 S_MINUS,
149 S_COMMENT_START,
150 S_COMMENT
151 } STATES;
152
153 #define BUF_SIZE 400
154
155 static List * names; //the names returned are strdup() , need to free out side
156 static char * comment;
157 static char section[BUF_SIZE/4];
158
159 static int parser_whatis(int fd)
160 {
161 static int init = 0;
162 int i,j,k,end;
163 static char buffer[BUF_SIZE];
164 char a,b,c;
165
166 if(!init) {
167 names = new List;
168 init ++;
169 }
170
171 names->delete_all();
172 i = 0;
173 end = 0;
174 STATES s = S_START;
175 while(!end) {
176 k = read(fd,&c,1);
177 //g_print("%c",c,k);
178 if(k == -1) g_error("key word task:reading from pipe:%s",g_strerror(errno));
179 if (k == 0 || c == 0x0a) {
180 if (s == S_COMMENT) {
181 buffer[i] = 0;
182 // add items to clist
183 //for(j = 0;j<names->get_size();j++) g_print("%s , ",(char*)names->get_item(j));
184 //g_print("section = %s, \tcomment = %s\n",section,buffer);
185 comment = buffer;
186 }
187 else if( s != S_START) {
188 if(context->get_value("show_warning"))
189 g_warning("parser error: unexpected end of %s",k?"line":"file");
190 comment = NULL;
191 }
192 end++;
193 continue;
194 }
195 switch (s) {
196 case S_START:
197 if(!is_blank(c)) {
198 s = S_NAME;
199 i = 0;
200 buffer[i++] = c;
201 }
202 break;
203 case S_NAME:
204 if( c == ',') {
205 s = S_NAME_END1;
206 buffer[i] = 0;
207 names->add_item(my_strdup(buffer));
208 } else if(is_blank(c)) {
209 s = S_NAME_END2;
210 }else {
211 buffer[i++] = c;
212 }
213 break;
214 case S_NAME_END1:
215 if(is_blank(c)) break;
216 else if(c == '(') {
217 s = S_SECTION;
218 i = 0;
219 }
220 else {
221 s = S_NAME;
222 i = 0;
223 buffer[i++] = c;
224 }
225 break;
226 case S_NAME_END2:
227 if(is_blank(c)) break;
228 else if(c == '(') {
229 buffer[i] = 0;
230 names->add_item(my_strdup(buffer));
231 s = S_SECTION;
232 i = 0;
233 } else if(c == ',') {
234 s = S_NAME_END1;
235 buffer[i] = 0;
236 names->add_item(my_strdup(buffer));
237 }
238 else {
239 s = S_NAME;
240 buffer[i++] = c;
241 }
242 break;
243 case S_SECTION:
244 if(is_blank(c)) break;
245 else if(c == ')') {
246 s = S_SECTION_END1;
247 if(i == 0) {
248 g_warning("parser error: unknown format");
249 }
250 else {
251 buffer[i] = 0;
252 strcpy(section,buffer);
253 }
254 }
255 else buffer[i++] = c;
256 break;
257 case S_SECTION_END1:
258 if(is_blank(c)) break;
259 else if(c == '-') s = S_SECTION_END2;
260 break;
261 case S_SECTION_END2:
262 if(is_blank(c)) s = S_COMMENT_START;
263 else g_warning("parser error: unknwn format");
264 break;
265 case S_COMMENT_START:
266 if(!is_blank(c)) {
267 s = S_COMMENT;
268 i = 0;
269 buffer[i++] = c;
270 }
271 break;
272 case S_COMMENT:
273 buffer[i++] = c;
274 break;
275 default: g_warning("parser error: unknow state");
276 }
277 }
278 //g_print("k = %d\n",k);
279 return k;
280 }
281
282 List * keyword_search_list;
283
284 static int key_word_search_taskfunc(int flag)
285 {
286 static int init = 0;
287 static char * parameter;
288 static int process_ID;
289 static int pipes[2];
290 static List * paths;
291 static char * path;
292 static int pipe_active; // pipe is in active
293 static int running; // pipe is in active
294 static int counter;
295
296 ManPath * man_path;
297 ManItem * man_item;
298 int i,j,k;
299 char file_name[BUF_SIZE], buffer[BUF_SIZE];
300 char * text[3];
301 char * s;
302
303 if(!init) {
304 pipe_active = 0;
305 running = 0;
306 paths = new List();
307 keyword_search_list = new List();
308 init ++;
309 }
310
311 //g_print("task key-word search ...\n");
312 if((flag & (TASK_START|TASK_STOP)) && pipe_active) {
313 //g_print("reset ...\n");
314 kill(process_ID,3);
315 close(pipes[0]);
316 pipe_active = 0;
317 running = 0;
318 gtk_widget_set_sensitive(stop_button,0);
319 //paths->delete_all();
320 }
321 if(flag & TASK_START) {
322 //g_print("starting ... key = %s\n",keyword);
323 running = 1;
324 gtk_widget_set_sensitive(stop_button,1);
325 paths->delete_all();
326 gtk_clist_clear(GTK_CLIST(clist3));
327 counter = 0;
328 j = man_paths->get_size();
329 for(i = 0;i<j;i++) paths->add_item(man_paths->get_name(i));
330 } else if( !pipe_active ) {
331 if(paths->get_size() == 0) {
332 running = 0;
333 gtk_widget_set_sensitive(stop_button,0);
334 } else {
335 path = (char*) paths->get_item(0);
336 paths->delete_item(0);
337 strcpy(buffer,"grep ");
338 strcat(buffer,keyword);
339 strcat(buffer," ");
340 attach(file_name,path,"whatis");
341 strcat(buffer,file_name);
342 strcat(buffer," ");
343
344 g_return_val_if_fail(!pipe(pipes),0);
345 process_ID = fork();
346 if(process_ID == -1) {g_warning("can not fork a new process");return 0;}
347 if(process_ID == 0) {
348 g_return_val_if_fail(close(pipes[0]) != -1,0);;
349 close(1);
350 g_return_val_if_fail(dup(pipes[1]) == 1,0);
351 g_return_val_if_fail(close(pipes[1]) != -1,0);
352 //write(1,"1234567890safdsfd%srfwfwefw",10);
353 //fprintf(stderr,"%s\n",buffer);
354 if(do_system_command(buffer,0));// g_warning("my_system returned a non-zero value!");
355 _exit(0);
356 }
357 close(pipes[1]);
358 pipe_active ++;
359 }
360 } else { //running, pipe in active
361 k = parser_whatis(pipes[0]);
362 if((j = names->get_size())) {
363 /*
364 for(i = 0;i<j;i++)
365 g_print(i?", %s":"%s",names->get_item(i));
366 g_print("(%s)",section);
367 g_print(" - %s\n",comment);
368 */
369 man_path = (ManPath*)man_paths->get_value(man_paths->search_item(path));
370 text[1] = section;
371 text[2] = "";
372 for(i = 0;i<j;i++) {
373 //g_print("point 0, man_item = %x\n",man_path);
374 s = (char*)names->get_item(i);
375 if(s[0] == '/') s = strrchr(s, '/') + 1;
376 man_item = (ManItem*)man_path->search_man_item(s,section);
377 //g_print("point 1\n");
378 if(context->get_value("show_warning"))
379 if (!man_item) g_warning("man item: %s (%s) could not found",names->get_item(i),section);
380 text[0] = (char*)names->get_item(i);
381 //g_print("point 2\n");
382 if(i == j-1) text[2] = comment;
383 pthread_mutex_lock(&gtk_lock);
384 gtk_clist_append(GTK_CLIST(clist3),text);
385 gtk_clist_set_row_data(GTK_CLIST(clist3),counter++,(gpointer)man_item);
386 pthread_mutex_unlock(&gtk_lock);
387 }
388 }
389 if(k == 0) {
390 close(pipes[0]);
391 pipe_active = 0;
392 //g_print("pipe closeing \n");
393 }
394 }
395 return running;
396 }
397
398 /******************* init thread **********************/
399 Task *task_init_man_data;
400 Task *task_extract_man_data;
401 Task *task_add_data_to_clist;
402 Task *task_loading_man_data;
403 Task *task_key_word_search;
404 void init_thread(TaskGroup * thread)
405 {
406 task_init_man_data = task_new(thread,0.3,(TaskRunFunc)init_man_data,NULL);
407 task_set_active(task_init_man_data);
408 task_extract_man_data = task_new(thread,0.5,(TaskRunFunc)extract_man_data,NULL);
409 task_set_active(task_extract_man_data);
410 task_add_data_to_clist = task_new(thread,0.7,(TaskRunFunc)add_data_to_clist,NULL);
411 task_set_active(task_add_data_to_clist);
412 task_loading_man_data = task_new(thread,0.31,(TaskRunFunc)loading_man_data,NULL);
413 task_key_word_search = task_new(thread,0.5,(TaskRunFunc)key_word_search_taskfunc,NULL);
414 }
0 #ifndef _TASKFUNC_H_
1 #define _TASKFUNC_H_
2 #include "task.h"
3
4 extern Task *task_init_man_data;
5 extern Task *task_extract_man_data;
6 extern Task *task_add_data_to_clist;
7 extern Task *task_loading_man_data;
8 extern Task *task_key_word_search;
9
10 void init_thread(TaskGroup * thread);
11 int init_man_data();
12
13 #endif
0 #include "kman.h"
1 #include <stdio.h>
2
3 void main()
4 {
5 ManPath a("/usr/man");
6 printf("size = %d",a.GetSize(1));
7 }
8
0 #include <stdio.h>
1 #include "context.h"
2
3 main()
4 {
5 int i;
6 AppContext context(NULL);
7 context.set_value("test",(void*)1234);
8 context.set_value("v_size",(void*)1024);
9 context.restore_default("test");
10 context.display_values();
11 i = (int)context.get_value("v_size");
12 printf("v_size = %d, h_size = %d, test = %d",i,context.get_value("h_size"),context.get_value("test"));
13 }
14
0 /*************** testdict.c ******************/
1
2 #include "list.h"
3 #include <stdio.h>
4
5 void main()
6 {
7 Dictionary * dict;
8 dict = new Dictionary;
9 dict->add_item("/usr/man",(void *)100);
10 dict->add_item("/usr/local/man",(void * )200);
11 printf("size = %d, /usr/man = %d\n",dict->get_size(),dict->get_value("/usr/local/man"));
12 }
0 #include "list.h"
1 #include <stdio.h>
2
3 void main()
4 {
5 List * a;
6 int i,j,k;
7 a = new List;
8 for (i = 0;i<100;i++)
9 {
10 a->add_item((void *)i);
11 }
12 a->delete_item(15);
13 j = 0;
14 while(!a->meet_end(j))
15 {
16 k = (int)a->get_item(j++);
17 printf("%d ,j = %d\n",k,j);
18 }
19 }
20
0 #include <stdlib.h>
1 #include <stdio.h>
2
3 void main()
4 {
5 int i;
6 void *a,*b;
7 for (i = 1;i<100;i++)
8 {
9 a = malloc(i);
10 b = malloc(1);
11 printf("i = %d, space = %d\n",i,b-a);
12 free(b);
13 free(a);
14 }
15 }
16
0 #include "task.h"
1 #include <stdio.h>
2 #include <unistd.h>
3
4 int task_runb(int state, void * data);
5 int task_runa(int state, void * data);
6
7 Task *a,*b;
8 void main()
9 {
10 TaskGroup * task_group;
11 task_group = task_group_new();
12 b = task_new(task_group,0.5,task_runb,"b");
13 a = task_new(task_group,0.4,task_runa,"a");
14 task_set_active(b);usleep(15000);
15 //task_set_active(a);
16 //task_set_active(b);
17 sleep(4);
18 }
19
20 int task_runa(int state, void* data)
21 {
22 static int i;
23 int j,k;
24 if(state&TASK_START)
25 {
26 printf("task a begain... state = %d",state);
27 write(1,"task a begin to run...\n",24);
28 i = 0;
29 //task_set_active(b);
30 }
31 for(j = 0;j < 100 && i< 2000;j++,i++) {
32 write(1,data,1);
33 }
34 usleep(1);
35 return (i<2000);
36 }
37
38 int task_runb(int state, void* data)
39 {
40 static int i;
41 int j,k;
42 if(state&TASK_START) i = 0;
43 for(j = 0;j < 100 && i< 1000;j++,i++)
44 write(1,data,1);
45 if(i==500) task_set_active(a);
46 write(1,"\n",1);
47 return (i<1000);
48 }
49
0 /*
1 * util.c
2 *
3 * Copyright (c) 1990, 1991, John W. Eaton.
4 *
5 * You may distribute under the terms of the GNU General Public
6 * License as specified in the file COPYING that comes with the man
7 * distribution.
8 *
9 * John W. Eaton
10 * jwe@che.utexas.edu
11 * Department of Chemical Engineering
12 * The University of Texas at Austin
13 * Austin, Texas 78712
14 */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include <stdlib.h>
19 #include <stdarg.h>
20 #include <ctype.h>
21 #include <signal.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <sys/wait.h>
25 #include <unistd.h>
26 #include <jerror.h>
27
28 #include "util.h"
29 #include "gripedefs.h"
30
31 int debug = 0;
32 char * progname = 0;
33
34 /*
35 * Extract last element of a name like /foo/bar/baz.
36 */
37 char *
38 mkprogname (char *s) {
39 char *t;
40
41 t = strrchr (s, '/');
42 if (t == (char *)NULL)
43 t = s;
44 else
45 t++;
46
47 return my_strdup (t);
48 }
49
50 /*
51 * Is file a nonempty and newer than file b?
52 *
53 * case:
54 *
55 * a newer than b returns 1
56 * a older than b returns 0
57 * stat on a fails or a empty returns -1
58 * stat on b fails or b empty returns -2
59 * both fail or empty returns -3
60 */
61 int
62 is_newer (char *fa, char *fb) {
63 struct stat fa_sb;
64 struct stat fb_sb;
65 register int fa_stat;
66 register int fb_stat;
67 register int status = 0;
68
69 fa_stat = stat (fa, &fa_sb);
70 if (fa_stat != 0 || fa_sb.st_size == 0)
71 status = 1;
72
73 fb_stat = stat (fb, &fb_sb);
74 if (fb_stat != 0 || fb_sb.st_size == 0)
75 status |= 2;
76
77 if (status != 0)
78 return -status;
79
80 return (fa_sb.st_mtime > fb_sb.st_mtime);
81 }
82
83 int ruid, rgid, euid, egid, suid;
84
85 void
86 get_permissions (void) {
87 ruid = getuid();
88 euid = geteuid();
89 rgid = getgid();
90 egid = getegid();
91 suid = (ruid != euid || rgid != egid);
92 }
93
94 void
95 no_privileges (void) {
96 if (suid) {
97 #ifndef __CYGWIN32__
98 setreuid(ruid, ruid);
99 setregid(rgid, rgid);
100 #endif
101 suid = 0;
102 }
103 }
104
105 /*
106 * Unfortunately, Linux libc system() ignores SIGINT and SIGQUIT
107 * The consequence is that "man -K" cannot be interrupted.
108 * Here a private copy that doesn't fiddle with signals.
109 * (But see below.)
110 */
111 static int
112 system0 (char *command) {
113 int pid, pid2, status;
114
115 pid = fork();
116 if (pid == -1) {
117 perror(progname);
118 fatal (CANNOT_FORK, command);
119 }
120 if (pid == 0) {
121 char *argv[4];
122 argv[0] = "sh";
123 argv[1] = "-c";
124 argv[2] = command;
125 argv[3] = 0;
126 execv("/bin/sh", argv); /* was: execve(*,*,environ); */
127 exit(127);
128 }
129 do {
130 pid2 = wait(&status);
131 if (pid2 == -1)
132 return -1;
133 } while(pid2 != pid);
134 return status;
135 }
136
137 /*
138 * What to do upon an interrupt? Experience shows that
139 * if we exit immediately, sh notices that its child has
140 * died and will try to fiddle with the tty.
141 * Simultaneously, also less will fiddle with the tty,
142 * resetting the mode before exiting.
143 * This leads to undesirable races. So, we catch SIGINT here
144 * and exit after the child has exited.
145 */
146 static int interrupted = 0;
147 static void catch_int(int a) {
148 interrupted = 1;
149 }
150
151 static int
152 system1 (char *command) {
153 void (*prev_handler)(int) = signal (SIGINT,catch_int);
154 int ret = system0(command);
155 if (interrupted)
156 exit(1);
157 signal(SIGINT,prev_handler);
158 return ret;
159 }
160
161 static int
162 my_system (char *command) {
163 int pid, pid2, status, stat;
164
165 if (!suid)
166 return system1 (command);
167
168 #ifdef _POSIX_SAVED_IDS
169
170 /* we need not fork */
171 setuid(ruid);
172 setgid(rgid);
173 status = system1(command);
174 setuid(euid);
175 setgid(egid);
176 return (WIFEXITED(status) ? WEXITSTATUS(status) : 127);
177 #endif
178
179 fflush(stdout); fflush(stderr);
180 pid = fork();
181 if (pid == -1) {
182 perror(progname);
183 fatal (CANNOT_FORK, command);
184 }
185 if (pid == 0) {
186 setuid(ruid);
187 setgid(rgid);
188 status = system1 (command);
189 exit(WIFEXITED(status) ? WEXITSTATUS(status) : 127);
190 }
191 pid2 = wait (&stat);
192 if (pid2 == -1) {
193 perror(progname);
194 fatal (WAIT_FAILED, command); /* interrupted? */
195 }
196 if (pid2 != pid)
197 fatal (GOT_WRONG_PID);
198 if (WIFEXITED(stat) && WEXITSTATUS(stat) != 127)
199 return WEXITSTATUS(stat);
200 fatal (CHILD_TERMINATED_ABNORMALLY, command);
201 return -1; /* not reached */
202 }
203
204 FILE *
205 my_popen(const char *command, const char *type) {
206 FILE *r;
207
208 if (!suid)
209 return popen(command, type);
210
211 #ifdef _POSIX_SAVED_IDS
212 setuid(ruid);
213 setgid(rgid);
214 r = popen(command, type);
215 setuid(euid);
216 setgid(egid);
217 return r;
218 #endif
219
220 no_privileges();
221 return popen(command, type);
222 }
223
224 /*
225 * Attempt a system () call.
226 */
227 int
228 do_system_command (char *command, int silent) {
229 int status = 0;
230
231 /*
232 * If we're debugging, don't really execute the command -- you never
233 * know what might be in that mangled string :-O.
234 */
235 if (debug == 1)
236 gripe (NO_EXEC, command);
237 else
238 status = my_system (command);
239
240 if (status && !silent)
241 gripe (SYSTEM_FAILED, command, status);
242
243 return status;
244 }
245
246 char *
247 my_malloc (int n) {
248 char *s = (char*) malloc(n);
249 if (!s)
250 fatal (OUT_OF_MEMORY, n);
251 return s;
252 }
253
254 char *
255 my_strdup (char *s) {
256 char *t = my_malloc(strlen(s) + 1);
257 strcpy(t, s);
258 return t;
259 }
260
261 /******************* modifyed by Wang XinKai ,1999.3.19 *********/
262 char *getmsg(int n)
263 {
264 static char buffer[100];
265 buffer[0] = 0;
266 //sprintf(buffer,"error, errorcode = %d\n",n);
267 return buffer;
268 }
269
270 void
271 gripe (int n, ...) {
272 va_list p;
273
274 va_start(p, n);
275 vfprintf (stderr, getmsg(n), p);
276 va_end(p);
277 fflush (stderr);
278 }
279
280 void
281 fatal (int n, ...) {
282 va_list p;
283 fprintf (stderr, "%s: ", progname);
284 va_start(p, n);
285 vfprintf (stderr, getmsg(n), p);
286 va_end(p);
287 exit (1);
288 }
289 /************************** modify end ************************/
0 /* functions and variables exported from util.c */
1
2 void get_permissions (void);
3 void no_privileges (void);
4 char *my_malloc (int n);
5 char *my_strdup (char *s);
6 char *mkprogname (char *s);
7 int is_newer (char *fa, char *fb);
8 int do_system_command (char *cmd, int silent);
9 FILE *my_popen(const char *cmd, const char *type);
10 void gripe (int n, ...);
11 void fatal (int n, ...);
12
13 extern int ruid, rgid, euid, egid, suid;
14 extern char * progname;
15 extern int debug;
0 /******************** departed from menu.c ***************/
1 /******************** window2.c **************************/
2
3 #include <stdio.h>
4 #include <gtk/gtk.h>
5 #include "menu.h"
6 #include "list.h"
7 #include "util.h"
8 #include "mandata.h"
9 #include "taskfunc.h"
10
11 static int window2_button_callback(GtkWidget *w, gpointer data);
12 static int window2_delete_event_callback(GtkWidget *w, GdkEvent *event,gpointer data);
13 static int clist2_select_callback(GtkWidget *w,int row, int column, GdkEvent *event,gpointer data);
14 static void entry2_activate_callback(GtkWidget *,gpointer);
15 static void entry2_changed_callback(GtkWidget *,gpointer);
16
17 int signal_window2_change; //used by window2_button_callback() to decide whether to take action or not
18 GtkWidget * window2 = NULL; //edit paths window
19
20 GtkWidget * clist2 = NULL;
21 int clist2_selected_row;
22
23 GtkWidget*
24 create_window2 ()
25 {
26 GtkWidget *window2;
27 GtkWidget *hbox3;
28 GtkWidget *vbox1;
29 GtkWidget *clist2;
30 GtkWidget *swindow;
31 GtkWidget *hbox4;
32 GtkWidget *button1;
33 GtkWidget *button2;
34 GtkWidget *vbox2;
35 GtkWidget *vbox3;
36 GtkWidget *button3;
37 GtkWidget *button4;
38 GtkWidget *button5;
39 GtkWidget *entry2;
40
41 gchar *titles[3] = { "a", "Path", "Items" };
42
43 window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
44 // GTK_WIDGET_UNSET_FLAGS (window2, GTK_CAN_FOCUS);
45 gtk_object_set_data (GTK_OBJECT (window2), "window2", window2);
46 gtk_window_set_title (GTK_WINDOW (window2), "edit man paths");
47 gtk_window_set_policy (GTK_WINDOW (window2), FALSE, TRUE, FALSE);
48 gtk_widget_set_usize(window2,300,220);
49
50 gtk_signal_connect(GTK_OBJECT(window2), "delete_event",
51 GTK_SIGNAL_FUNC(window2_delete_event_callback),
52 (void*)1);
53
54 hbox3 = gtk_hbox_new (FALSE, 10);
55 gtk_object_set_data (GTK_OBJECT (window2), "hbox3", hbox3);
56 gtk_widget_show (hbox3);
57 gtk_container_add (GTK_CONTAINER (window2), hbox3);
58 gtk_container_border_width (GTK_CONTAINER (hbox3), 10);
59
60 vbox1 = gtk_vbox_new (FALSE, 10);
61 gtk_object_set_data (GTK_OBJECT (window2), "vbox1", vbox1);
62 gtk_widget_show (vbox1);
63 gtk_box_pack_start (GTK_BOX (hbox3), vbox1, TRUE, TRUE, 0);
64
65 vbox3 = gtk_vbox_new (FALSE, 0);
66 gtk_object_set_data (GTK_OBJECT (window2), "vbox3", vbox1);
67 gtk_widget_show (vbox3);
68 gtk_box_pack_start (GTK_BOX (vbox1), vbox3, TRUE, TRUE, 0);
69
70 clist2 = gtk_clist_new_with_titles( 3, titles);
71 ::clist2 = clist2;
72 swindow = gtk_scrolled_window_new (NULL, NULL);
73 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
74 GTK_POLICY_AUTOMATIC,
75 GTK_POLICY_AUTOMATIC);
76
77 //GTK_WIDGET_UNSET_FLAGS (swindow, GTK_CAN_FOCUS);
78
79 gtk_clist_set_column_width(GTK_CLIST(clist2),0,10);
80 gtk_clist_set_column_width(GTK_CLIST(clist2),1,130);
81 gtk_clist_set_column_justification(GTK_CLIST(clist2),0,GTK_JUSTIFY_CENTER);
82 gtk_clist_set_column_justification(GTK_CLIST(clist2),2,GTK_JUSTIFY_RIGHT);
83 gtk_clist_set_selection_mode(GTK_CLIST(clist2),GTK_SELECTION_SINGLE);
84 gtk_clist_column_titles_passive(GTK_CLIST(clist2));
85 gtk_container_add (GTK_CONTAINER (swindow), clist2);
86 gtk_signal_connect(GTK_OBJECT(clist2),"select_row",GTK_SIGNAL_FUNC(clist2_select_callback),(void*)1);
87 gtk_signal_connect(GTK_OBJECT(clist2),"unselect_row",GTK_SIGNAL_FUNC(clist2_select_callback),(void*)0);
88
89 gtk_object_set_data (GTK_OBJECT (window2), "clist2", clist2);
90 gtk_widget_show (clist2);
91 gtk_widget_show (swindow);
92 gtk_box_pack_start (GTK_BOX (vbox3), swindow, TRUE, TRUE, 0);
93
94 entry2 = gtk_entry_new_with_max_length (200);
95 gtk_object_set_data (GTK_OBJECT (window2), "entry2", entry2);
96 gtk_widget_show (entry2);
97 gtk_box_pack_start (GTK_BOX (vbox3), entry2, FALSE, FALSE, 0);
98 gtk_signal_connect(GTK_OBJECT(entry2),"activate",GTK_SIGNAL_FUNC(entry2_activate_callback),NULL);
99 gtk_signal_connect(GTK_OBJECT(entry2),"changed",GTK_SIGNAL_FUNC(entry2_changed_callback),NULL);
100 gtk_tooltips_set_tip (tooltips, entry2, "Input new path here", NULL);
101
102
103 hbox4 = gtk_hbox_new (TRUE, 15);
104 gtk_object_set_data (GTK_OBJECT (window2), "hbox4", hbox4);
105 gtk_widget_show (hbox4);
106 gtk_box_pack_end (GTK_BOX (vbox1), hbox4, FALSE, TRUE, 0);
107
108 button1 = gtk_button_new_with_label ("OK");
109 gtk_object_set_data (GTK_OBJECT (window2), "button1", button1);
110 gtk_widget_show (button1);
111 gtk_box_pack_start (GTK_BOX (hbox4), button1, TRUE, FALSE, 0);
112 gtk_signal_connect (GTK_OBJECT(button1),"clicked",(GtkSignalFunc)window2_button_callback,(void*)1);
113 GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
114 gtk_widget_grab_default (button1);
115
116 button2 = gtk_button_new_with_label ("apply");
117 gtk_object_set_data (GTK_OBJECT (window2), "button2", button2);
118 gtk_widget_show (button2);
119 gtk_box_pack_start (GTK_BOX (hbox4), button2, TRUE, FALSE, 0);
120 gtk_signal_connect (GTK_OBJECT(button2),"clicked",(GtkSignalFunc)window2_button_callback,(void*)2);
121
122 vbox2 = gtk_vbox_new (FALSE, 0);
123 gtk_object_set_data (GTK_OBJECT (window2), "vbox2", vbox2);
124 gtk_widget_show (vbox2);
125 gtk_box_pack_start (GTK_BOX (hbox3), vbox2, FALSE, TRUE, 0);
126
127 button3 = gtk_button_new_with_label ("Add new");
128 gtk_object_set_data (GTK_OBJECT (window2), "button3", button3);
129 gtk_widget_show (button3);
130 gtk_box_pack_start (GTK_BOX (vbox2), button3, FALSE, FALSE, 15);
131 gtk_signal_connect (GTK_OBJECT(button3),"clicked",(GtkSignalFunc)window2_button_callback,(void*)3);
132 gtk_widget_set_sensitive(button3,0);
133
134 button4 = gtk_button_new_with_label ("Delete");
135 gtk_object_set_data (GTK_OBJECT (window2), "button4", button4);
136 gtk_widget_show (button4);
137 gtk_box_pack_start (GTK_BOX (vbox2), button4, FALSE, FALSE, 0);
138 gtk_signal_connect (GTK_OBJECT(button4),"clicked",(GtkSignalFunc)window2_button_callback,(void*)4);
139 gtk_widget_set_sensitive(button4,0);
140
141 button5 = gtk_button_new_with_label ("Default");
142 gtk_object_set_data (GTK_OBJECT (window2), "button5", button5);
143 gtk_widget_show (button5);
144 gtk_box_pack_start (GTK_BOX (vbox2), button5, FALSE, FALSE, 15);
145 gtk_signal_connect (GTK_OBJECT(button5),"clicked",(GtkSignalFunc)window2_button_callback,(void*)5);
146
147 button5 = gtk_button_new_with_label ("Reload");
148 gtk_object_set_data (GTK_OBJECT (window2), "button6", button5);
149 gtk_widget_show (button5);
150 gtk_box_pack_start (GTK_BOX (vbox2), button5, FALSE, FALSE, 0);
151 gtk_signal_connect (GTK_OBJECT(button5),"clicked",(GtkSignalFunc)window2_button_callback,(void*)6);
152
153 button5 = gtk_button_new_with_label ("Reload all");
154 gtk_object_set_data (GTK_OBJECT (window2), "button7", button5);
155 gtk_widget_show (button5);
156 gtk_box_pack_start (GTK_BOX (vbox2), button5, FALSE, FALSE, 15);
157 gtk_signal_connect (GTK_OBJECT(button5),"clicked",(GtkSignalFunc)window2_button_callback,(void*)7);
158
159 return window2;
160 }
161
162 /******************* tool functions ***********************/
163 void load_clist2()
164 {
165 int i,j;
166 ManPath * p;
167 gchar * clist_item[3];
168 gchar buffer[100];
169 j = man_paths->get_size();
170 gtk_clist_clear(GTK_CLIST(clist2));
171 for (i = 0;i<j;i++) {
172 p = (ManPath*) man_paths->get_value(i);
173 if (p) {
174 clist_item[0] = p->active?"o":"";
175 clist_item[1] = man_paths->get_name(i);
176 sprintf(buffer,"%d",p->GetSize(-1));
177 clist_item[2] = buffer;
178 }
179 else {
180 clist_item[0] = "o";
181 clist_item[1] = man_paths->get_name(i);
182 clist_item[2] = "???";
183 }
184 gtk_clist_append(GTK_CLIST(clist2),clist_item);
185 }
186 }
187
188 /******************* interfaces to outside***********************/
189 int edit_paths_callback(GtkWidget *w, gpointer data)
190 {
191 GtkWidget * apply_button,*delete_button,*focus;
192 if (!window2) {
193 window2 = create_window2();
194 man_paths_to_be_load = new List;
195 clist2_selected_row = -1;
196 }
197 apply_button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(window2),"button2");
198 gtk_widget_set_sensitive(apply_button,0);
199 delete_button = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(window2),"button4");
200 gtk_widget_set_sensitive(delete_button,0);
201 signal_window2_change = 0;
202 load_clist2();
203 gtk_widget_show(window2);
204 focus = (GtkWidget*) gtk_object_get_data(GTK_OBJECT(window2),"button1");
205 gtk_widget_grab_focus (focus);
206 }
207
208 /******************* call backs ***********************/
209 static int window2_delete_event_callback(GtkWidget *w, GdkEvent * event, gpointer data)
210 {
211 GtkWidget * ok_button;
212 ok_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(w),"button1");
213 gtk_signal_emit_by_name(GTK_OBJECT(ok_button),"clicked");
214 return 1;
215 }
216
217 static int window2_button_callback(GtkWidget *w, gpointer data)
218 {
219 GtkWidget * x, *apply_button,*add_new_button;
220 gchar * c, *c2;
221 int i;
222 int select = (int)data;
223 gchar * clist_item[3];
224 // printf("point2 data = %d\n",select);
225 apply_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button2");
226 add_new_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button3");
227 switch(select) {
228 case 1: gtk_widget_hide(window2); //OK
229 case 2: //Apply
230 if(signal_window2_change) {
231 task_set_active(task_extract_man_data);
232 task_set_active(task_add_data_to_clist);
233 }
234 signal_window2_change = 0;
235 gtk_widget_set_sensitive(apply_button,0);
236 break;
237 case 3: //Add New
238 x = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"entry2");
239 c = gtk_entry_get_text(GTK_ENTRY(x));
240 if(!strcmp(c,"")) {
241 g_print("g-man: path name can not be empty\n");
242 break;
243 }
244 if (man_paths->have_item(c)) break;
245 c2 = my_strdup(c);
246 clist_item[0] = "o";
247 clist_item[1] = c2;
248 clist_item[2] = "???";
249 gtk_clist_append(GTK_CLIST(clist2),clist_item);
250 man_paths->add_item(c2,(void*)0);
251 man_paths_to_be_load->add_item(c2);
252 task_set_active(task_loading_man_data);
253 signal_window2_change ++;
254 gtk_widget_set_sensitive(apply_button,1);
255 gtk_editable_select_region (GTK_EDITABLE (x), 0, strlen(c));
256 break;
257 case 4: //Delete
258 if (clist2_selected_row == -1) break;
259 // printf("remove %d\n",clist2_selected_row);
260 i = clist2_selected_row;
261 delete ((ManPath*)(man_paths->get_value(i)));
262 man_paths->delete_item(i);
263 gtk_clist_remove(GTK_CLIST(clist2),i);
264 signal_window2_change ++;
265 gtk_widget_set_sensitive(apply_button,1);
266 break;
267 default:
268 g_print("g-man: sorry... this function not implementd yet, please wait for the future version\n");
269 };
270 return 1;
271 }
272
273 static int clist2_select_callback(GtkWidget *w,int row, int column, GdkEvent *event,gpointer data)
274 {
275 GtkWidget * delete_button;
276 delete_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button4");
277 if(data) {
278 clist2_selected_row = row;
279 }
280 else {
281 if (clist2_selected_row == row) clist2_selected_row = -1;
282 }
283 gtk_widget_set_sensitive(delete_button,clist2_selected_row != -1);
284 return 0;
285 }
286
287 static void entry2_activate_callback(GtkWidget *w,gpointer data)
288 {
289 GtkWidget * add_new_button;
290 add_new_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button3");
291 // printf("button3 = %x\n",add_new_button);
292 gtk_signal_emit_by_name(GTK_OBJECT(add_new_button),"clicked");
293 }
294
295 static void entry2_changed_callback(GtkWidget *w,gpointer data)
296 {
297 GtkWidget * add_new_button;
298 add_new_button = (GtkWidget*)gtk_object_get_data(GTK_OBJECT(window2),"button3");
299 // printf("button3 = %x\n",add_new_button);
300 gtk_widget_set_sensitive(add_new_button,strcmp("",gtk_entry_get_text(GTK_ENTRY(w))));
301 }
0 #ifndef _WINDOW2_H_
1 #define _WINDOW2_H_
2 #include <gtk/gtk.h>
3
4 int edit_paths_callback(GtkWidget *w, gpointer data);
5
6 extern GtkWidget * clist2;
7
8 #endif