1 /*
2  * Copyright (c) Tony Bybell 2005-2009.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  */
9 
10 #include "globals.h"
11 #include <config.h>
12 #include <gtk/gtk.h>
13 #include "gtk12compat.h"
14 #include "symbol.h"
15 #include "ptranslate.h"
16 #include "pipeio.h"
17 #include "debug.h"
18 
19 #ifdef _MSC_VER
20 #define strcasecmp _stricmp
21 #endif
22 
init_proctrans_data(void)23 void init_proctrans_data(void)
24 {
25 int i;
26 
27 if(!GLOBALS->procsel_filter) { GLOBALS->procsel_filter = calloc_2(PROC_FILTER_MAX+1, sizeof(char *)); }
28 if(!GLOBALS->proc_filter) { GLOBALS->proc_filter = calloc_2(PROC_FILTER_MAX+1, sizeof(struct pipe_ctx *)); }
29 
30 for(i=0;i<PROC_FILTER_MAX+1;i++)
31 	{
32 	GLOBALS->procsel_filter[i] = NULL;
33 	GLOBALS->proc_filter[i] = NULL;
34 	}
35 }
36 
remove_all_proc_filters(void)37 void remove_all_proc_filters(void)
38 {
39 struct Global *GLOBALS_cache = GLOBALS;
40 unsigned int i, j;
41 
42 for(j=0;j<GLOBALS->num_notebook_pages;j++)
43 	{
44 	GLOBALS = (*GLOBALS->contexts)[j];
45 
46 	if(GLOBALS)
47 		{
48 		for(i=1;i<PROC_FILTER_MAX+1;i++)
49 			{
50 			if(GLOBALS->proc_filter[i])
51 				{
52 				pipeio_destroy(GLOBALS->proc_filter[i]);
53 				GLOBALS->proc_filter[i] = NULL;
54 				}
55 
56 			if(GLOBALS->procsel_filter[i])
57 				{
58 				free_2(GLOBALS->procsel_filter[i]);
59 				GLOBALS->procsel_filter[i] = NULL;
60 				}
61 			}
62 		}
63 
64 	GLOBALS = GLOBALS_cache;
65 	}
66 }
67 
68 
regen_display(void)69 static void regen_display(void)
70 {
71 GLOBALS->signalwindow_width_dirty=1;
72 MaxSignalLength();
73 signalarea_configure_event(GLOBALS->signalarea, NULL);
74 wavearea_configure_event(GLOBALS->wavearea, NULL);
75 }
76 
77 
78 /*
79  * this is likely obsolete
80  */
81 #if 0
82 static void remove_proc_filter(int which, int regen)
83 {
84 if(GLOBALS->proc_filter[which])
85 	{
86 	pipeio_destroy(GLOBALS->proc_filter[which]);
87 	GLOBALS->proc_filter[which] = NULL;
88 
89 	if(regen)
90 	        {
91 		regen_display();
92 	        }
93 	}
94 }
95 #endif
96 
load_proc_filter(int which,char * name)97 static void load_proc_filter(int which, char *name)
98 {
99 
100   FILE *stream;
101 
102   char *cmd;
103   char exec_name[1025];
104   char abs_path [1025];
105   char* arg, end;
106   int result;
107 
108   exec_name[0] = 0;
109   abs_path[0]  = 0;
110 
111   /* if name has arguments grab only the first word (the name of the executable)*/
112   sscanf(name, "%s ", exec_name);
113 
114   arg = name + strlen(exec_name);
115 
116   /* remove leading spaces from argument */
117   while (isspace((int)(unsigned char)arg[0])) {
118     arg++;
119   }
120 
121   /* remove trailing spaces from argument */
122   if (strlen(arg) > 0) {
123 
124     end = strlen(arg) - 1;
125 
126     while (arg[(int)end] == ' ') {
127       arg[(int)end] = 0;
128       end--;
129     }
130   }
131 
132   /* turn the exec_name into an absolute path */
133 #if !defined __MINGW32__ && !defined _MSC_VER
134   cmd = (char *)malloc_2(strlen(exec_name)+6+1);
135   sprintf(cmd, "which %s", exec_name);
136   stream = popen(cmd, "r");
137 
138   result = fscanf(stream, "%s", abs_path);
139 
140   if((strlen(abs_path) == 0)||(!result))
141     {
142       status_text("Could not find filter process!\n");
143       pclose(stream); /* cppcheck */
144       return;
145     }
146 
147   pclose(stream);
148   free_2(cmd);
149 #else
150   strcpy(abs_path, exec_name);
151 #endif
152 
153 
154   /* remove_proc_filter(which, 0); ... should never happen from GUI, but perhaps possible from save files or other weirdness */
155   if(!GLOBALS->ttrans_filter[which])
156 	{
157 	GLOBALS->proc_filter[which] = pipeio_create(abs_path, arg);
158 	}
159 }
160 
install_proc_filter(int which)161 int install_proc_filter(int which)
162 {
163 int found = 0;
164 
165 if((which<0)||(which>=(PROC_FILTER_MAX+1)))
166         {
167         which = 0;
168         }
169 
170 if(GLOBALS->traces.first)
171         {
172         Trptr t = GLOBALS->traces.first;
173         while(t)
174                 {
175                 if(t->flags&TR_HIGHLIGHT)
176                         {
177                         if(!(t->flags&(TR_BLANK|TR_ANALOG_BLANK_STRETCH)))
178                                 {
179 				t->f_filter = 0;
180                                 t->p_filter = which;
181 				if(!which)
182 					{
183 					t->flags &= (~(TR_FTRANSLATED|TR_PTRANSLATED|TR_ANALOGMASK));
184 					}
185 					else
186 					{
187 					t->flags &= (~(TR_ANALOGMASK));
188 					t->flags |= TR_PTRANSLATED;
189 					}
190                                 found++;
191                                 }
192                         }
193                 t=t->t_next;
194                 }
195         }
196 
197 if(found)
198 	{
199 	regen_display();
200 	}
201 
202 return(found);
203 }
204 
205 /************************************************************************/
206 
207 
208 
destroy_callback(GtkWidget * widget,GtkWidget * nothing)209 static void destroy_callback(GtkWidget *widget, GtkWidget *nothing)
210 {
211 (void)widget;
212 (void)nothing;
213 
214 GLOBALS->is_active_ptranslate_c_2=0;
215 gtk_widget_destroy(GLOBALS->window_ptranslate_c_5);
216 GLOBALS->window_ptranslate_c_5 = NULL;
217 }
218 
ok_callback(GtkWidget * widget,GtkWidget * nothing)219 static void ok_callback(GtkWidget *widget, GtkWidget *nothing)
220 {
221 install_proc_filter(GLOBALS->current_filter_ptranslate_c_1);
222 destroy_callback(widget, nothing);
223 }
224 
select_row_callback(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)225 static void select_row_callback(GtkWidget *widget, gint row, gint column,
226 	GdkEventButton *event, gpointer data)
227 {
228 (void)widget;
229 (void)row;
230 (void)column;
231 (void)event;
232 (void)data;
233 
234 GLOBALS->current_filter_ptranslate_c_1 = row + 1;
235 }
236 
unselect_row_callback(GtkWidget * widget,gint row,gint column,GdkEventButton * event,gpointer data)237 static void unselect_row_callback(GtkWidget *widget, gint row, gint column,
238 	GdkEventButton *event, gpointer data)
239 {
240 (void)widget;
241 (void)row;
242 (void)column;
243 (void)event;
244 (void)data;
245 
246 GLOBALS->current_filter_ptranslate_c_1 = 0; /* none */
247 }
248 
249 
add_filter_callback_2(GtkWidget * widget,GtkWidget * nothing)250 static void add_filter_callback_2(GtkWidget *widget, GtkWidget *nothing)
251 {
252 (void)widget;
253 (void)nothing;
254 
255 int i;
256 GtkCList *cl;
257 
258 if(!GLOBALS->filesel_ok) { return; }
259 
260 if(*GLOBALS->fileselbox_text)
261 	{
262 	for(i=0;i<GLOBALS->num_proc_filters;i++)
263 		{
264 		if(GLOBALS->procsel_filter[i])
265 			{
266 			if(!strcmp(GLOBALS->procsel_filter[i], *GLOBALS->fileselbox_text))
267 				{
268 				status_text("Filter already imported.\n");
269 				if(GLOBALS->is_active_ptranslate_c_2) gdk_window_raise(GLOBALS->window_ptranslate_c_5->window);
270 				return;
271 				}
272 			}
273 		}
274 	}
275 
276 GLOBALS->num_proc_filters++;
277 load_proc_filter(GLOBALS->num_proc_filters, *GLOBALS->fileselbox_text);
278 if(GLOBALS->proc_filter[GLOBALS->num_proc_filters])
279 	{
280 	if(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]) free_2(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]);
281 	GLOBALS->procsel_filter[GLOBALS->num_proc_filters] = malloc_2(strlen(*GLOBALS->fileselbox_text) + 1);
282 	strcpy(GLOBALS->procsel_filter[GLOBALS->num_proc_filters], *GLOBALS->fileselbox_text);
283 
284 	cl=GTK_CLIST(GLOBALS->clist_ptranslate_c_2);
285 	gtk_clist_freeze(cl);
286 	gtk_clist_append(cl,(gchar **)&(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]));
287 
288 	gtk_clist_set_column_width(cl,0,gtk_clist_optimal_column_width(cl,0));
289 	gtk_clist_thaw(cl);
290 	}
291 	else
292 	{
293 	GLOBALS->num_proc_filters--;
294 	}
295 
296 if(GLOBALS->is_active_ptranslate_c_2) gdk_window_raise(GLOBALS->window_ptranslate_c_5->window);
297 }
298 
add_filter_callback(GtkWidget * widget,GtkWidget * nothing)299 static void add_filter_callback(GtkWidget *widget, GtkWidget *nothing)
300 {
301 (void)widget;
302 (void)nothing;
303 
304 if(GLOBALS->num_proc_filters == PROC_FILTER_MAX)
305 	{
306 	status_text("Max number of process filters installed already.\n");
307 	return;
308 	}
309 
310 fileselbox("Select Filter Process",&GLOBALS->fcurr_ptranslate_c_1,GTK_SIGNAL_FUNC(add_filter_callback_2), GTK_SIGNAL_FUNC(NULL),"*", 0);
311 }
312 
313 /*
314  * mainline..
315  */
ptrans_searchbox(char * title)316 void ptrans_searchbox(char *title)
317 {
318     int i;
319 
320     GtkWidget *scrolled_win;
321     GtkWidget *vbox1, *hbox, *hbox0;
322     GtkWidget *button1, *button5, *button6;
323     gchar *titles[]={"Process Filter Select"};
324     GtkWidget *frame2, *frameh, *frameh0;
325     GtkWidget *table;
326     GtkTooltips *tooltips;
327 
328     if(GLOBALS->is_active_ptranslate_c_2)
329 	{
330 	gdk_window_raise(GLOBALS->window_ptranslate_c_5->window);
331 	return;
332 	}
333 
334     GLOBALS->is_active_ptranslate_c_2=1;
335     GLOBALS->current_filter_ptranslate_c_1 = 0;
336 
337     /* create a new modal window */
338     GLOBALS->window_ptranslate_c_5 = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
339     install_focus_cb(GLOBALS->window_ptranslate_c_5, ((char *)&GLOBALS->window_ptranslate_c_5) - ((char *)GLOBALS));
340 
341     gtk_window_set_title(GTK_WINDOW (GLOBALS->window_ptranslate_c_5), title);
342     gtkwave_signal_connect(GTK_OBJECT (GLOBALS->window_ptranslate_c_5), "delete_event",(GtkSignalFunc) destroy_callback, NULL);
343 
344     tooltips=gtk_tooltips_new_2();
345 
346     table = gtk_table_new (256, 1, FALSE);
347     gtk_widget_show (table);
348 
349     vbox1 = gtk_vbox_new (FALSE, 0);
350     gtk_container_border_width (GTK_CONTAINER (vbox1), 3);
351     gtk_widget_show (vbox1);
352 
353 
354     frame2 = gtk_frame_new (NULL);
355     gtk_container_border_width (GTK_CONTAINER (frame2), 3);
356     gtk_widget_show(frame2);
357 
358     gtk_table_attach (GTK_TABLE (table), frame2, 0, 1, 0, 254,
359                         GTK_FILL | GTK_EXPAND,
360                         GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1);
361 
362     GLOBALS->clist_ptranslate_c_2=gtk_clist_new_with_titles(1,titles);
363     gtk_clist_column_titles_passive(GTK_CLIST(GLOBALS->clist_ptranslate_c_2));
364 
365     gtk_clist_set_selection_mode(GTK_CLIST(GLOBALS->clist_ptranslate_c_2), GTK_SELECTION_EXTENDED);
366     gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_ptranslate_c_2), "select_row",GTK_SIGNAL_FUNC(select_row_callback),NULL);
367     gtkwave_signal_connect_object (GTK_OBJECT (GLOBALS->clist_ptranslate_c_2), "unselect_row",GTK_SIGNAL_FUNC(unselect_row_callback),NULL);
368 
369     for(i=0;i<GLOBALS->num_proc_filters;i++)
370 	{
371 	gtk_clist_append(GTK_CLIST(GLOBALS->clist_ptranslate_c_2),(gchar **)&(GLOBALS->procsel_filter[i+1]));
372 	}
373     gtk_clist_set_column_width(GTK_CLIST(GLOBALS->clist_ptranslate_c_2),0,gtk_clist_optimal_column_width(GTK_CLIST(GLOBALS->clist_ptranslate_c_2),0));
374 
375     gtk_widget_show (GLOBALS->clist_ptranslate_c_2);
376 
377     scrolled_win = gtk_scrolled_window_new (NULL, NULL);
378     gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
379                                       GTK_POLICY_AUTOMATIC,
380                                       GTK_POLICY_AUTOMATIC);
381     gtk_widget_set_usize( GTK_WIDGET (scrolled_win), -1, 300);
382     gtk_widget_show(scrolled_win);
383 
384     /* gtk_scrolled_window_add_with_viewport doesn't seen to work right here.. */
385     gtk_container_add (GTK_CONTAINER (scrolled_win), GLOBALS->clist_ptranslate_c_2);
386 
387     gtk_container_add (GTK_CONTAINER (frame2), scrolled_win);
388 
389 
390     frameh0 = gtk_frame_new (NULL);
391     gtk_container_border_width (GTK_CONTAINER (frameh0), 3);
392     gtk_widget_show(frameh0);
393     gtk_table_attach (GTK_TABLE (table), frameh0, 0, 1, 254, 255,
394                         GTK_FILL | GTK_EXPAND,
395                         GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1);
396 
397 
398     hbox0 = gtk_hbox_new (FALSE, 1);
399     gtk_widget_show (hbox0);
400 
401     button6 = gtk_button_new_with_label (" Add Proc Filter to List ");
402     gtk_container_border_width (GTK_CONTAINER (button6), 3);
403     gtkwave_signal_connect_object (GTK_OBJECT (button6), "clicked",GTK_SIGNAL_FUNC(add_filter_callback),GTK_OBJECT (GLOBALS->window_ptranslate_c_5));
404     gtk_widget_show (button6);
405     gtk_tooltips_set_tip_2(tooltips, button6,
406 		"Bring up a file requester to add a process filter to the filter select window.",NULL);
407 
408     gtk_box_pack_start (GTK_BOX (hbox0), button6, TRUE, FALSE, 0);
409     gtk_container_add (GTK_CONTAINER (frameh0), hbox0);
410 
411     frameh = gtk_frame_new (NULL);
412     gtk_container_border_width (GTK_CONTAINER (frameh), 3);
413     gtk_widget_show(frameh);
414     gtk_table_attach (GTK_TABLE (table), frameh, 0, 1, 255, 256,
415                         GTK_FILL | GTK_EXPAND,
416                         GTK_FILL | GTK_EXPAND | GTK_SHRINK, 1, 1);
417 
418 
419     hbox = gtk_hbox_new (FALSE, 1);
420     gtk_widget_show (hbox);
421 
422     button1 = gtk_button_new_with_label (" OK ");
423     gtk_container_border_width (GTK_CONTAINER (button1), 3);
424     gtkwave_signal_connect_object (GTK_OBJECT (button1), "clicked",GTK_SIGNAL_FUNC(ok_callback),GTK_OBJECT (GLOBALS->window_ptranslate_c_5));
425     gtk_widget_show (button1);
426     gtk_tooltips_set_tip_2(tooltips, button1,
427 		"Add selected signals to end of the display on the main window.",NULL);
428 
429     gtk_box_pack_start (GTK_BOX (hbox), button1, TRUE, FALSE, 0);
430 
431     button5 = gtk_button_new_with_label (" Cancel ");
432     gtk_container_border_width (GTK_CONTAINER (button5), 3);
433     gtkwave_signal_connect_object (GTK_OBJECT (button5), "clicked",GTK_SIGNAL_FUNC(destroy_callback),GTK_OBJECT (GLOBALS->window_ptranslate_c_5));
434     gtk_tooltips_set_tip_2(tooltips, button5,
435 		"Do nothing and return to the main window.",NULL);
436     gtk_widget_show (button5);
437     gtk_box_pack_start (GTK_BOX (hbox), button5, TRUE, FALSE, 0);
438 
439     gtk_container_add (GTK_CONTAINER (frameh), hbox);
440     gtk_container_add (GTK_CONTAINER (GLOBALS->window_ptranslate_c_5), table);
441 
442     gtk_widget_set_usize(GTK_WIDGET(GLOBALS->window_ptranslate_c_5), 400, 400);
443     gtk_widget_show(GLOBALS->window_ptranslate_c_5);
444 }
445 
446 
447 /*
448  * currently only called by parsewavline
449  */
set_current_translate_proc(char * name)450 void set_current_translate_proc(char *name)
451 {
452 int i;
453 
454 for(i=1;i<GLOBALS->num_proc_filters+1;i++)
455 	{
456 	if(!strcmp(GLOBALS->procsel_filter[i], name)) { GLOBALS->current_translate_proc = i; return; }
457 	}
458 
459 if(GLOBALS->num_proc_filters < PROC_FILTER_MAX)
460 	{
461 	GLOBALS->num_proc_filters++;
462 	load_proc_filter(GLOBALS->num_proc_filters, name);
463 	if(!GLOBALS->proc_filter[GLOBALS->num_proc_filters])
464 		{
465 		GLOBALS->num_proc_filters--;
466 		GLOBALS->current_translate_proc = 0;
467 		}
468 		else
469 		{
470 		if(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]) free_2(GLOBALS->procsel_filter[GLOBALS->num_proc_filters]);
471 		GLOBALS->procsel_filter[GLOBALS->num_proc_filters] = malloc_2(strlen(name) + 1);
472 		strcpy(GLOBALS->procsel_filter[GLOBALS->num_proc_filters], name);
473 		GLOBALS->current_translate_proc = GLOBALS->num_proc_filters;
474 		}
475 	}
476 }
477 
478 
479