1 /*
2  * Copyright (c) Tony Bybell 1999-2010.
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 <ctype.h>
14 #include "debug.h"
15 #include "symbol.h"
16 #include "currenttime.h"
17 #include "fgetdynamic.h"
18 
19 /* only for use locally */
20 struct wave_logfile_lines_t
21 {
22 struct wave_logfile_lines_t *next;
23 char *text;
24 };
25 
26 struct logfile_instance_t
27 {
28 struct logfile_instance_t *next;
29 GtkWidget *window;
30 GtkWidget *text;
31 
32 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
33 GtkTextTag *bold_tag;
34 GtkTextTag *mono_tag;
35 GtkTextTag *size_tag;
36 #else
37 GdkFont *font_logfile;
38 #endif
39 
40 char default_text[1];
41 };
42 
43 #define log_collection (*((struct logfile_instance_t **)GLOBALS->logfiles))
44 
45 
46 /* Add some text to our text widget - this is a callback that is invoked
47 when our window is realized. We could also force our window to be
48 realized with gtk_widget_realize, but it would have to be part of
49 a hierarchy first */
50 
51 
log_text(GtkWidget * text,GdkFont * font,char * str)52 void log_text(GtkWidget *text, GdkFont *font, char *str)
53 {
54 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
55 (void)font;
56 
57 gtk_text_buffer_insert_with_tags (GTK_TEXT_VIEW (text)->buffer, &GLOBALS->iter_logfile_c_2,
58                                  str, -1, GLOBALS->mono_tag_logfile_c_1, GLOBALS->size_tag_logfile_c_1, NULL);
59 #else
60 gtk_text_insert (GTK_TEXT (text), font, &text->style->black, NULL, str, -1);
61 #endif
62 }
63 
log_text_bold(GtkWidget * text,GdkFont * font,char * str)64 void log_text_bold(GtkWidget *text, GdkFont *font, char *str)
65 {
66 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
67 (void)font;
68 
69 gtk_text_buffer_insert_with_tags (GTK_TEXT_VIEW (text)->buffer, &GLOBALS->iter_logfile_c_2,
70                                  str, -1, GLOBALS->bold_tag_logfile_c_2, GLOBALS->mono_tag_logfile_c_1, GLOBALS->size_tag_logfile_c_1, NULL);
71 #else
72 gtk_text_insert (GTK_TEXT (text), font, &text->style->fg[GTK_STATE_SELECTED], &text->style->bg[GTK_STATE_SELECTED], str, -1);
73 #endif
74 }
75 
76 static void
log_realize_text(GtkWidget * text,gpointer data)77 log_realize_text (GtkWidget *text, gpointer data)
78 {
79 (void)text;
80 (void)data;
81 
82 /* nothing for now */
83 }
84 
85 
center_op(void)86 static void center_op(void)
87 {
88 TimeType middle=0, width;
89 
90 if((GLOBALS->tims.marker<0)||(GLOBALS->tims.marker<GLOBALS->tims.first)||(GLOBALS->tims.marker>GLOBALS->tims.last))
91 	{
92         if(GLOBALS->tims.end>GLOBALS->tims.last) GLOBALS->tims.end=GLOBALS->tims.last;
93         middle=(GLOBALS->tims.start/2)+(GLOBALS->tims.end/2);
94         if((GLOBALS->tims.start&1)&&(GLOBALS->tims.end&1)) middle++;
95         }
96         else
97         {
98         middle=GLOBALS->tims.marker;
99         }
100 
101 width=(TimeType)(((gdouble)GLOBALS->wavewidth)*GLOBALS->nspx);
102 GLOBALS->tims.start=time_trunc(middle-(width/2));
103 if(GLOBALS->tims.start+width>GLOBALS->tims.last) GLOBALS->tims.start=time_trunc(GLOBALS->tims.last-width);
104 if(GLOBALS->tims.start<GLOBALS->tims.first) GLOBALS->tims.start=GLOBALS->tims.first;
105 GTK_ADJUSTMENT(GLOBALS->wave_hslider)->value=GLOBALS->tims.timecache=GLOBALS->tims.start;
106 
107 fix_wavehadj();
108 
109 gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "changed"); /* force zoom update */
110 gtk_signal_emit_by_name (GTK_OBJECT (GTK_ADJUSTMENT(GLOBALS->wave_hslider)), "value_changed"); /* force zoom update */
111 }
112 
113 
114 
115 static gboolean
button_release_event(GtkWidget * text,GdkEventButton * event)116 button_release_event (GtkWidget *text, GdkEventButton *event)
117 {
118 (void)event;
119 
120 gchar *sel;
121 
122 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
123 GtkTextIter start;
124 GtkTextIter end;
125 
126 if (gtk_text_buffer_get_selection_bounds (GTK_TEXT_VIEW(text)->buffer,
127                                          &start, &end))
128        {
129        if(gtk_text_iter_compare (&start, &end) < 0)
130                {
131                sel = gtk_text_buffer_get_text(GTK_TEXT_VIEW(text)->buffer,
132                                               &start, &end, FALSE);
133 
134                if(sel)
135                        {
136 			int slen = strlen(sel);
137 			char *sel2 = NULL;
138 
139                        	if((slen)&&(sel[0]>='0')&&(sel[0]<='9'))
140                                {
141 			       TimeType tm;
142 			       gunichar gch = gtk_text_iter_get_char(&end);
143 			       int do_si_append = 0;
144 
145 			        if(gch==' ') /* in case time is of format "100 ps" with a space */
146 					{
147 					gtk_text_iter_forward_char(&end);
148 					gch = gtk_text_iter_get_char(&end);
149 					}
150 
151 				if((sel[slen-1]>='0')&&(sel[slen-1]<='9')) /* need to append units? */
152 					{
153 					int silen = strlen(WAVE_SI_UNITS);
154 					int silp;
155 
156 					gch = tolower(gch);
157 					if(gch == 's')
158 						{
159 						do_si_append = 1;
160 						}
161 					else
162 						{
163 						for(silp=0;silp<silen;silp++)
164 							{
165 							if((unsigned)gch == (unsigned)WAVE_SI_UNITS[silp])
166 								{
167 								do_si_append = 1;
168 								break;
169 								}
170 							}
171 						}
172 					}
173 
174 				if(do_si_append)
175 					{
176 					sel2 = malloc_2(slen + 2);
177 					sprintf(sel2, "%s%c", sel, (unsigned char)gch);
178 					}
179 
180                                tm = unformat_time(sel2 ? sel2 : sel, GLOBALS->time_dimension);
181                                if((tm >= GLOBALS->tims.first) && (tm <= GLOBALS->tims.last))
182                                        {
183                                        GLOBALS->tims.lmbcache = -1;
184                                        update_markertime(GLOBALS->tims.marker = tm);
185                                        center_op();
186                                        signalarea_configure_event(GLOBALS->signalarea, NULL);
187                                        wavearea_configure_event(GLOBALS->wavearea, NULL);
188                                        update_markertime(GLOBALS->tims.marker = tm); /* centering problem in GTK2 */
189                                        }
190                                }
191 
192 		       if(sel2) { free_2(sel2); }
193                        g_free(sel);
194                        }
195                }
196        }
197 #else
198 
199 #ifndef WAVE_USE_GTK2
200 GtkEditable *oe = GTK_EDITABLE(&GTK_TEXT(text)->editable);
201 GtkTextClass *tc = (GtkTextClass *) ((GtkObject*) (GTK_OBJECT(text)))->klass;
202 GtkEditableClass *oec = &tc->parent_class;
203 #else
204 GtkOldEditable *oe = GTK_OLD_EDITABLE(&GTK_TEXT(text)->old_editable);
205 GtkOldEditableClass *oec = GTK_OLD_EDITABLE_GET_CLASS(oe);
206 #endif
207 
208 if(oe->has_selection)
209 	{
210 	if(oec->get_chars)
211 		{
212 	 	sel = oec->get_chars(oe, oe->selection_start_pos, oe->selection_end_pos);
213 
214 		if(sel)
215 			{
216 			int slen = strlen(sel);
217 			char *sel2 = NULL;
218 
219 			if((slen)&&(sel[0]>='0')&&(sel[0]<='9'))
220 				{
221 				TimeType tm;
222 				gint gchpos = oe->selection_end_pos;
223 				gchar *extra = oec->get_chars(oe, gchpos, gchpos+2);
224 				gchar gch = extra ? extra[0] : 0;
225 			        int do_si_append = 0;
226 
227 			        if(gch==' ') /* in case time is of format "100 ps" with a space */
228 					{
229 					gch = gch ? extra[1] : 0;
230 					}
231 
232 				if(extra) g_free(extra);
233 
234 				if((sel[slen-1]>='0')&&(sel[slen-1]<='9')) /* need to append units? */
235 					{
236 					int silen = strlen(WAVE_SI_UNITS);
237 					int silp;
238 
239 					gch = tolower(gch);
240 					if(gch == 's')
241 						{
242 						do_si_append = 1;
243 						}
244 					else
245 						{
246 						for(silp=0;silp<silen;silp++)
247 							{
248 							if(gch == WAVE_SI_UNITS[silp])
249 								{
250 								do_si_append = 1;
251 								break;
252 								}
253 							}
254 						}
255 					}
256 
257 				if(do_si_append)
258 					{
259 					sel2 = malloc_2(slen + 2);
260 					sprintf(sel2, "%s%c", sel, (unsigned char)gch);
261 					}
262 
263 				tm = unformat_time(sel2 ? sel2 : sel, GLOBALS->time_dimension);
264 				if((tm >= GLOBALS->tims.first) && (tm <= GLOBALS->tims.last))
265 					{
266 					GLOBALS->tims.lmbcache = -1;
267 				        update_markertime(GLOBALS->tims.marker = tm);
268 					center_op();
269 					signalarea_configure_event(GLOBALS->signalarea, NULL);
270         				wavearea_configure_event(GLOBALS->wavearea, NULL);
271 				        update_markertime(GLOBALS->tims.marker = tm); /* centering problem in GTK2 */
272 					}
273 				}
274 
275 		        if(sel2) { free_2(sel2); }
276 			g_free(sel);
277 			}
278 		}
279 	}
280 
281 #endif
282 
283 return(FALSE); /* call remaining handlers... */
284 }
285 
286 /* Create a scrolled text area that displays a "message" */
create_log_text(GtkWidget ** textpnt)287 static GtkWidget *create_log_text (GtkWidget **textpnt)
288 {
289 GtkWidget *text;
290 GtkWidget *table;
291 GtkWidget *vscrollbar;
292 
293 /* Create a table to hold the text widget and scrollbars */
294 table = gtk_table_new (1, 16, FALSE);
295 
296 /* Put a text widget in the upper left hand corner. Note the use of
297 * GTK_SHRINK in the y direction */
298 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
299 text = gtk_text_view_new ();
300 gtk_text_buffer_get_start_iter (gtk_text_view_get_buffer(GTK_TEXT_VIEW (text)), &GLOBALS->iter_logfile_c_2);
301 GLOBALS->bold_tag_logfile_c_2 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (text)->buffer, "bold",
302                                       "weight", PANGO_WEIGHT_BOLD, NULL);
303 GLOBALS->mono_tag_logfile_c_1 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (text)->buffer, "monospace", "family", "monospace", NULL);
304 
305 GLOBALS->size_tag_logfile_c_1 = gtk_text_buffer_create_tag (GTK_TEXT_VIEW (text)->buffer, "fsiz",
306 			      "size", (GLOBALS->use_big_fonts ? 12 : 8) * PANGO_SCALE, NULL);
307 
308 
309 #else
310 text = gtk_text_new (NULL, NULL);
311 #endif
312 *textpnt = text;
313 gtk_table_attach (GTK_TABLE (table), text, 0, 14, 0, 1,
314                         GTK_FILL | GTK_EXPAND,
315                         GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0);
316 gtk_widget_set_usize(GTK_WIDGET(text), 100, 100);
317 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
318 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), TRUE);
319 #else
320 gtk_text_set_editable(GTK_TEXT(text), TRUE);
321 #endif
322 gtk_widget_show (text);
323 
324 /* And a VScrollbar in the upper right */
325 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
326 {
327 GtkTextViewClass *tc = (GtkTextViewClass*)GTK_OBJECT_GET_CLASS(GTK_OBJECT(text));
328 
329 tc->set_scroll_adjustments(GTK_TEXT_VIEW (text), NULL, NULL);
330 vscrollbar = gtk_vscrollbar_new (GTK_TEXT_VIEW (text)->vadjustment);
331 }
332 #else
333 vscrollbar = gtk_vscrollbar_new (GTK_TEXT (text)->vadj);
334 #endif
335 gtk_table_attach (GTK_TABLE (table), vscrollbar, 15, 16, 0, 1,
336                         GTK_FILL, GTK_FILL | GTK_SHRINK | GTK_EXPAND, 0, 0);
337 gtk_widget_show (vscrollbar);
338 
339 /* Add a handler to put a message in the text widget when it is realized */
340 gtk_signal_connect (GTK_OBJECT (text), "realize", GTK_SIGNAL_FUNC (log_realize_text), NULL);
341 
342 gtk_signal_connect(GTK_OBJECT(text), "button_release_event", GTK_SIGNAL_FUNC(button_release_event), NULL);
343 
344 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
345 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_CHAR);
346 #else
347 gtk_text_set_word_wrap(GTK_TEXT(text), FALSE);
348 gtk_text_set_line_wrap(GTK_TEXT(text), TRUE);
349 #endif
350 return(table);
351 }
352 
353 /***********************************************************************************/
354 
ok_callback(GtkWidget * widget,GtkWidget * cached_window)355 static void ok_callback(GtkWidget *widget, GtkWidget *cached_window)
356 {
357 (void)widget;
358 
359 struct logfile_instance_t *l = log_collection;
360 struct logfile_instance_t *lprev = NULL;
361 
362 while(l)
363 	{
364 	if(l->window == cached_window)
365 		{
366 		if(lprev)
367 			{
368 			lprev->next = l->next;
369 			}
370 			else
371 			{
372 			log_collection = l->next;
373 			}
374 
375 		free(l);  /* deliberately not free_2 */
376 		break;
377 		}
378 
379 	lprev = l;
380 	l = l->next;
381 	}
382 
383   DEBUG(printf("OK\n"));
384   gtk_widget_destroy(cached_window);
385 }
386 
387 
destroy_callback(GtkWidget * widget,GtkWidget * cached_window)388 static void destroy_callback(GtkWidget *widget, GtkWidget *cached_window)
389 {
390 (void)cached_window;
391 
392 ok_callback(widget, widget);
393 }
394 
395 
logbox(char * title,int width,char * default_text)396 void logbox(char *title, int width, char *default_text)
397 {
398     GtkWidget *window;
399     GtkWidget *vbox;
400     GtkWidget *hbox, *button1;
401     GtkWidget *label, *separator;
402     GtkWidget *ctext;
403     GtkWidget *text;
404     struct logfile_instance_t *log_c;
405 
406     FILE *handle;
407     struct wave_logfile_lines_t *wlog_head=NULL, *wlog_curr=NULL;
408     int wlog_size = 0;
409 
410     handle = fopen(default_text, "rb");
411     if(!handle)
412 	{
413 	char *buf = malloc_2(strlen(default_text)+128);
414 	sprintf(buf, "Could not open logfile '%s'\n", default_text);
415 	status_text(buf);
416 	free_2(buf);
417 	return;
418 	}
419 
420     /* fix problem where ungrab doesn't occur if button pressed + simultaneous accelerator key occurs */
421     if(GLOBALS->in_button_press_wavewindow_c_1) { gdk_pointer_ungrab(GDK_CURRENT_TIME); }
422 
423 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
424 /* nothing */
425 #else
426     if(!GLOBALS->font_logfile_c_1)
427 	{
428 	if(GLOBALS->fontname_logfile)
429 		{
430 		GLOBALS->font_logfile_c_1=gdk_font_load(GLOBALS->fontname_logfile);
431 		}
432 
433 	if(!GLOBALS->font_logfile_c_1)
434 		{
435 #ifndef __CYGWIN__
436 		 GLOBALS->font_logfile_c_1=gdk_font_load(GLOBALS->use_big_fonts
437 				? "-*-courier-*-r-*-*-18-*-*-*-*-*-*-*"
438 				: "-*-courier-*-r-*-*-10-*-*-*-*-*-*-*");
439 #else
440 		 GLOBALS->font_logfile_c_1=gdk_font_load(GLOBALS->use_big_fonts
441 				? "-misc-fixed-*-*-*-*-18-*-*-*-*-*-*-*"
442 				: "-misc-fixed-*-*-*-*-10-*-*-*-*-*-*-*");
443 
444 #endif
445 		}
446 	}
447 #endif
448 
449     /* create a new nonmodal window */
450     window = gtk_window_new(GLOBALS->disable_window_manager ? GTK_WINDOW_POPUP : GTK_WINDOW_TOPLEVEL);
451     if(GLOBALS->use_big_fonts || GLOBALS->fontname_logfile)
452 	{
453     	gtk_widget_set_usize( GTK_WIDGET (window), width*1.8, 600);
454 	}
455 	else
456 	{
457     	gtk_widget_set_usize( GTK_WIDGET (window), width, 400);
458 	}
459     gtk_window_set_title(GTK_WINDOW (window), title);
460 
461     gtk_signal_connect(GTK_OBJECT (window), "delete_event", (GtkSignalFunc) destroy_callback, window);
462 
463     vbox = gtk_vbox_new (FALSE, 0);
464     gtk_container_add (GTK_CONTAINER (window), vbox);
465     gtk_widget_show (vbox);
466 
467     label=gtk_label_new(default_text);
468     gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
469     gtk_widget_show (label);
470 
471     separator = gtk_hseparator_new ();
472     gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
473     gtk_widget_show (separator);
474 
475     ctext=create_log_text(&text);
476     gtk_box_pack_start (GTK_BOX (vbox), ctext, TRUE, TRUE, 0);
477     gtk_widget_show (ctext);
478 
479     separator = gtk_hseparator_new ();
480     gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, TRUE, 0);
481     gtk_widget_show (separator);
482 
483     hbox = gtk_hbox_new (FALSE, 1);
484     gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
485     gtk_widget_show (hbox);
486 
487     button1 = gtk_button_new_with_label ("Close Logfile");
488     gtk_widget_set_usize(button1, 100, -1);
489     gtk_signal_connect(GTK_OBJECT (button1), "clicked", GTK_SIGNAL_FUNC(ok_callback), window);
490     gtk_widget_show (button1);
491     gtk_container_add (GTK_CONTAINER (hbox), button1);
492     GTK_WIDGET_SET_FLAGS (button1, GTK_CAN_DEFAULT);
493     gtk_signal_connect_object (GTK_OBJECT (button1), "realize", (GtkSignalFunc) gtk_widget_grab_default, GTK_OBJECT (button1));
494 
495     gtk_widget_show(window);
496 
497     log_text_bold(text, NULL, "Click-select");
498     log_text(text, NULL, " on numbers to jump to that time value in the wave viewer.\n");
499     log_text(text, NULL, " \n");
500 
501     while(!feof(handle))
502 	{
503 	char *pnt = fgetmalloc(handle);
504 	if(pnt)
505 		{
506 		struct wave_logfile_lines_t *w = calloc_2(1, sizeof(struct wave_logfile_lines_t));
507 
508 		wlog_size += (GLOBALS->fgetmalloc_len+1);
509 		w->text = pnt;
510 		if(!wlog_curr) { wlog_head = wlog_curr = w; } else { wlog_curr->next = w; wlog_curr = w; }
511 		}
512 	}
513 
514     if(wlog_curr)
515 	{
516 	struct wave_logfile_lines_t *w = wlog_head;
517 	struct wave_logfile_lines_t *wt;
518 	char *pnt = malloc_2(wlog_size + 1);
519 	char *pnt2 = pnt;
520 
521 	while(w)
522 		{
523 		int len = strlen(w->text);
524 		memcpy(pnt2, w->text, len);
525 		pnt2 += len;
526 		*pnt2 = '\n';
527 		pnt2++;
528 
529 		free_2(w->text);
530 		wt = w;
531 		w = w->next;
532 		free_2(wt);
533 		}
534 	/* wlog_head = */ wlog_curr = NULL; /* scan-build */
535 	*pnt2 = 0;
536 	log_text(text, GLOBALS->font_logfile_c_1, pnt);
537 	free_2(pnt);
538 	}
539 
540     fclose(handle);
541 
542     log_c = calloc(1, sizeof(struct logfile_instance_t) + strlen(default_text));  /* deliberately not calloc_2, needs to be persistent! */
543     strcpy(log_c->default_text, default_text);
544     log_c->window = window;
545     log_c->text = text;
546     log_c->next = log_collection;
547 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
548     log_c->bold_tag = GLOBALS->bold_tag_logfile_c_2;
549     log_c->mono_tag = GLOBALS->mono_tag_logfile_c_1;
550     log_c->size_tag = GLOBALS->size_tag_logfile_c_1;
551 #else
552     log_c->font_logfile = GLOBALS->font_logfile_c_1;
553 #endif
554     log_collection = log_c;
555 }
556 
557 
logbox_reload_single(GtkWidget * window,GtkWidget * text,char * default_text)558 static void logbox_reload_single(GtkWidget *window, GtkWidget *text, char *default_text)
559 {
560 (void)window;
561 
562     FILE *handle;
563     struct wave_logfile_lines_t *wlog_head=NULL, *wlog_curr=NULL;
564     int wlog_size = 0;
565 
566     handle = fopen(default_text, "rb");
567     if(!handle)
568 	{
569 	char *buf = malloc_2(strlen(default_text)+128);
570 	sprintf(buf, "Could not open logfile '%s'\n", default_text);
571 	status_text(buf);
572 	free_2(buf);
573 	return;
574 	}
575 
576 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
577     {
578     GtkTextIter st_iter, en_iter;
579 
580     gtk_text_buffer_get_start_iter(GTK_TEXT_VIEW (text)->buffer, &st_iter);
581     gtk_text_buffer_get_end_iter(GTK_TEXT_VIEW (text)->buffer, &en_iter);
582     gtk_text_buffer_delete(GTK_TEXT_VIEW (text)->buffer, &st_iter, &en_iter);
583 
584     gtk_text_buffer_get_start_iter (GTK_TEXT_VIEW (text)->buffer, &GLOBALS->iter_logfile_c_2);
585     }
586 #else
587     {
588     guint len = gtk_text_get_length(GTK_TEXT(text));
589     gtk_text_set_point(GTK_TEXT(text), 0);
590 
591     gtk_text_freeze(GTK_TEXT(text));
592     gtk_text_forward_delete (GTK_TEXT(text), len);
593     }
594 #endif
595 
596     log_text_bold(text, NULL, "Click-select");
597     log_text(text, NULL, " on numbers to jump to that time value in the wave viewer.\n");
598     log_text(text, NULL, " \n");
599 
600     while(!feof(handle))
601 	{
602 	char *pnt = fgetmalloc(handle);
603 	if(pnt)
604 		{
605 		struct wave_logfile_lines_t *w = calloc_2(1, sizeof(struct wave_logfile_lines_t));
606 
607 		wlog_size += (GLOBALS->fgetmalloc_len+1);
608 		w->text = pnt;
609 		if(!wlog_curr) { wlog_head = wlog_curr = w; } else { wlog_curr->next = w; wlog_curr = w; }
610 		}
611 	}
612 
613     if(wlog_curr)
614 	{
615 	struct wave_logfile_lines_t *w = wlog_head;
616 	struct wave_logfile_lines_t *wt;
617 	char *pnt = malloc_2(wlog_size + 1);
618 	char *pnt2 = pnt;
619 
620 	while(w)
621 		{
622 		int len = strlen(w->text);
623 		memcpy(pnt2, w->text, len);
624 		pnt2 += len;
625 		*pnt2 = '\n';
626 		pnt2++;
627 
628 		free_2(w->text);
629 		wt = w;
630 		w = w->next;
631 		free_2(wt);
632 		}
633 	/* wlog_head = */ wlog_curr = NULL; /* scan-build */
634 	*pnt2 = 0;
635 	log_text(text, GLOBALS->font_logfile_c_1, pnt);
636 	free_2(pnt);
637 	}
638 
639 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
640 #else
641     gtk_text_thaw(GTK_TEXT(text));
642 #endif
643 
644     fclose(handle);
645 }
646 
647 
logbox_reload(void)648 void logbox_reload(void)
649 {
650 struct logfile_instance_t *l = log_collection;
651 
652 while(l)
653 	{
654 #if defined(WAVE_USE_GTK2) && !defined(GTK_ENABLE_BROKEN)
655 	GLOBALS->bold_tag_logfile_c_2 = l->bold_tag;
656 	GLOBALS->mono_tag_logfile_c_1 = l->mono_tag;
657 	GLOBALS->size_tag_logfile_c_1 = l->size_tag;
658 #else
659 	GLOBALS->font_logfile_c_1 = l->font_logfile;
660 #endif
661 
662 	logbox_reload_single(l->window, l->text, l->default_text);
663 	l = l->next;
664 	}
665 }
666 
667