Exemplo n.º 1
0
/*!
  \brief load_gui_tabs_pf() is called after interrogation completes 
  successfully. It's purpose is to load all the glade files and datamaps 
  as specified in the interrogation profile of the detected firmware. 
  \param notebook is the pointer to the notebook the new tab should be placed
  \param page is the page number to load
  \returns TRUE on success, FALSE on failure
  */
G_MODULE_EXPORT gboolean load_actual_tab(GtkNotebook *notebook, gint page)
{
	ConfigFile *cfgfile = NULL;
	gchar * map_file = NULL;
	gchar * glade_file = NULL;
	gchar * tmpbuf = NULL;
	GladeXML *xml = NULL;
	GtkWidget *label = NULL;
	GtkWidget *topframe = NULL;
	GtkWidget *placeholder = NULL;
	GHashTable *groups = NULL;
	GList *tab_widgets = NULL;
	BindGroup *bindgroup = NULL;
	extern GdkColor red;

	ENTER();
	placeholder =  gtk_notebook_get_nth_page(notebook,page);
	label = gtk_notebook_get_tab_label(notebook,placeholder);

	glade_file = (gchar *)OBJ_GET(label,"glade_file");
	map_file = (gchar *)OBJ_GET(label,"datamap_file");
	xml = glade_xml_new(glade_file,"topframe",NULL);
	g_return_val_if_fail(xml,FALSE);
	thread_update_logbar("interr_view",NULL,g_strdup(_("Load of tab: ")),FALSE,FALSE);
	thread_update_logbar("interr_view","info", g_strdup_printf("\"%s\"",glade_file),FALSE,FALSE);
	thread_update_logbar("interr_view",NULL,g_strdup(_(" completed.\n")),FALSE,FALSE);
	thread_update_logbar("interr_view",NULL,g_strdup(_("Load of tabconf: ")),FALSE,FALSE);
	thread_update_logbar("interr_view","info", g_strdup_printf("\"%s\"",map_file),FALSE,FALSE);
	cfgfile = cfg_open_file(map_file);
	if (cfgfile)
	{
		topframe = glade_xml_get_widget(xml,"topframe");
		if (topframe == NULL)
		{
			MTXDBG(TABLOADER|CRITICAL,_("\"topframe\" not found in xml, ABORTING!!\n"));
			set_title(g_strdup(_("ERROR Gui Tab XML problem, \"topframe\" element not found!!!")));
			EXIT();
			return FALSE;
		}
		OBJ_SET_FULL(topframe,"glade_xml",(gpointer)xml,g_object_unref);
		// bind_data() is recursive and will take 
		// care of all children

		bindgroup = g_new0(BindGroup,1);
		groups = load_groups(cfgfile);
		bindgroup->cfgfile = cfgfile;
		bindgroup->groups = groups;
		bindgroup->map_file = g_strdup(map_file);
/*		tab_widgets = g_list_prepend(tab_widgets,topframe);
		OBJ_SET(topframe,"tab_widgets",tab_widgets);
		*/
		bindgroup->topframe = topframe;
		bind_data(topframe,(gpointer)bindgroup);
		g_free(bindgroup->map_file);
		if (groups)
			g_hash_table_destroy(groups);
		groups = NULL;
		/* Clear not_rendered flag */
		OBJ_SET(label,"not_rendered",NULL);

		populate_master(topframe,(gpointer)cfgfile);

		gtk_box_pack_start(GTK_BOX(placeholder),topframe,TRUE,TRUE,0);
		OBJ_SET(placeholder,"topframe",topframe);
		glade_xml_signal_autoconnect(xml);
		g_free(bindgroup);
		if (cfg_read_string(cfgfile,"global","post_functions",&tmpbuf))
		{
			run_post_functions(tmpbuf);
			g_free(tmpbuf);
		}
		cfg_free(cfgfile);
		gtk_widget_show(topframe);
		/*printf("Current length of tab_widgets is %i\n",g_list_length(OBJ_GET(topframe,"tab_widgets")));*/
		thread_update_logbar("interr_view",NULL,g_strdup(_(" completed.\n")),FALSE,FALSE);
	}
	update_groups_pf();
	update_sources_pf();
	/* Allow gui to update as it should.... */
	gdk_flush();
	EXIT();
	return TRUE;
}
Exemplo n.º 2
0
/*!
  \brief bind_data() is a recursive function that is called for every container
  widget in a glade frame and it's purpose is to search the datamap file passed
  for the widget names in the glade file and if it's fond in the datamap to
  load all the attribues listed and bind them to the object using GTK+'s
  object model.
  \param widget is the widget passed to load attributes on
  \param user_data is the pointer to a BingGroup structure.
  */
G_MODULE_EXPORT void bind_data(GtkWidget *widget, gpointer user_data)
{
	BindGroup *bindgroup = (BindGroup *)user_data;
	ConfigFile *cfgfile = bindgroup->cfgfile;
	GHashTable *groups = bindgroup->groups;
	gchar * tmpbuf = NULL;
	gchar * section = NULL;
	gchar ** keys = NULL;
	gint num_keys = 0;
	gint offset = 0;
	gint page = 0;
	gint index = 0;
	gchar * initializer = NULL;
	GdkColor color;
	gchar *size = NULL;
	gint count = 0;
	gint tmpi = 0;
	gboolean hidden = FALSE;
	gchar *ptr = NULL;
	gchar **vector = NULL;
	gchar **vec2 = NULL;
	void (*func)(void) = NULL;
	GList *list = NULL;
	GList *list2 = NULL;
	const gchar *name = NULL;
	gboolean indexed = FALSE;
	Firmware_Details *firmware = NULL;
	GList ***ecu_widgets = NULL;
	GList *tab_widgets = NULL;
	void (*load_dep_obj)(GObject *, ConfigFile *,const gchar *,const gchar *) = NULL;

	ENTER();
	MTXDBG(TABLOADER,_("Entered"));
	ecu_widgets = (GList ***)DATA_GET(global_data,"ecu_widgets");
	firmware = (Firmware_Details *)DATA_GET(global_data,"firmware");

	g_return_if_fail(ecu_widgets);
	g_return_if_fail(firmware);

	if (!GTK_IS_WIDGET(widget))
	{
		EXIT();
		return;
	}

	if (GTK_IS_WIDGET(widget))
		if (GTK_IS_CONTAINER(widget))
			gtk_container_foreach(GTK_CONTAINER(widget),bind_data,user_data);
	name = gtk_widget_get_name(widget);
	if (!name)
	{
		EXIT();
		return;
	}

	if (NULL != (ptr = g_strrstr_len(name,strlen(name),"_of_")))
	{
		indexed = TRUE;
		ptr = g_strrstr_len(name,ptr-name,"_");
		tmpbuf = g_strdelimit(g_strdup(ptr),"_",' ');
		section = g_strndup(name,ptr-name);
		/*printf("(indexed) section is %s\n",section);*/
		gint result = sscanf(tmpbuf,"%d of %d",&index,&count);
		/*printf("sscanf result %i\n",result);*
		* printf("Found indexed value for \"%s\", index %i, count %i\n",tmpbuf,index,count);
		*/
		g_free(tmpbuf);
	}
	else
		section = g_strdup(name);

	if(cfg_read_string(cfgfile, section, "keys", &tmpbuf))
	{
		keys = parse_keys(tmpbuf,&num_keys,",");
		MTXDBG(TABLOADER,_("Number of keys for %s is %i\n"),section,num_keys);
		g_free(tmpbuf);
	}
	else 
	{
		g_free(section);
		EXIT();
		return;
	}

	page = -1;
	/* Store ptr to self in qdata, needed for bind_to_lists from groups*/
	OBJ_SET(widget,"self",widget);
	/* Bind the data in the "defaults" group per tab to EVERY var in that
	 * tab
	 */
	page = bind_group_data(cfgfile, G_OBJECT(widget), groups, "defaults");

	if(cfg_read_string(cfgfile, section, "group", &tmpbuf))
	{
		page = bind_group_data(cfgfile,G_OBJECT(widget),groups,tmpbuf);
		g_free(tmpbuf);
	}

	if ((!cfg_read_int(cfgfile, section, "page", &page)) && (page == -1))
	{
		MTXDBG(TABLOADER|CRITICAL,_("Object %s doesn't have a page assigned!!!!\n"),section);	

	}
	/* Bind widgets to lists if they have the bind_to_list flag set...
	 */
	tmpbuf = NULL;
	if (cfg_read_string(cfgfile, section, "bind_to_list", &tmpbuf))
	{
		bind_to_lists(widget, tmpbuf);
		g_free(tmpbuf);
	}
	if (cfg_read_boolean(cfgfile,section,"ellipsize",&tmpi))
	{
		if ((GTK_IS_LABEL(widget)) && (tmpi))
		{
			OBJ_SET(widget,"ellipsize_preferred",GINT_TO_POINTER(TRUE));
			if (DATA_GET(global_data,"ellipsize_tabs"))
				gtk_label_set_ellipsize(GTK_LABEL(widget),PANGO_ELLIPSIZE_END);
		}
	}

	/* Color selections */
	if (cfg_read_string(cfgfile, section, "active_fg", &tmpbuf))
	{
		gdk_color_parse(tmpbuf, &color);
		gtk_widget_modify_fg(widget, GTK_STATE_NORMAL, &color);
		g_free(tmpbuf);
	}
	if (cfg_read_string(cfgfile, section, "inactive_fg", &tmpbuf))
	{
		gdk_color_parse(tmpbuf, &color);
		gtk_widget_modify_fg(widget, GTK_STATE_INSENSITIVE, &color);
		g_free(tmpbuf);
	}

	/* If this widget has a "depend_on" tag we need to load the dependancy
	 * information  and store it for use when needed...
	 */
	if (cfg_read_string(cfgfile,section,"depend_on",&tmpbuf))
	{
		if (get_symbol("load_dependencies_obj",(void **)&load_dep_obj))
			load_dep_obj(G_OBJECT(widget),cfgfile,section,"depend_on");
		g_free(tmpbuf);
	}

	/* If this widget (a textview) has "create_tags" we call a special
	 * handler just for that..
	 */
	if (cfg_read_string(cfgfile,section,"create_tags",&tmpbuf))
	{
		load_tags(G_OBJECT(widget),cfgfile,section);
		g_free(tmpbuf);
	}

	/* If this widget has "tooltip" set the tip on the widget */
	if (cfg_read_string(cfgfile,section,"tooltip",&tmpbuf))
	{
		gtk_widget_set_tooltip_text(widget,tmpbuf);
		g_free(tmpbuf);
	}

	/* If this widget (a label) has "set_label" we set the label on it
	 */
	if (cfg_read_string(cfgfile,section,"set_label",&tmpbuf))
	{
/*		printf("setting label on %s to \"%s\"\n",glade_get_widget_name(widget),tmpbuf);*/
		gtk_label_set_text(GTK_LABEL(widget),tmpbuf);
		g_free(tmpbuf);
	}

	/* If this widget is temp dependant, set the current units on it 
	 */
	if (cfg_read_string(cfgfile,section,"temp_dep",&tmpbuf))
	{
		OBJ_SET(widget,"widget_temp",DATA_GET(global_data,"mtx_temp_units"));
		g_free(tmpbuf);
	}

	/* If this widget has "register_as", register it with the supplied name
	 */
	if (cfg_read_string(cfgfile,section,"register_as",&tmpbuf))
	{
		register_widget(tmpbuf,widget);
		g_free(tmpbuf);
	}
	/* If this widget has visible_functions defined */
	if (cfg_read_string(cfgfile,section,"visible_functions",&tmpbuf))
	{
		vector = g_strsplit(tmpbuf,",",-1);
		g_free(tmpbuf);
		for (guint i=0;i<g_strv_length(vector);i++)
		{
			vec2 = g_strsplit(vector[i],":",2);
			if (g_strv_length(vec2) != 2)
			{
				printf("ERROR in %s, visible_functions param is missing the framerate parameter (func:fps)\n",cfgfile->filename);
				g_strfreev(vec2);
				continue;
			}
			gint fps = (GINT)g_strtod(vec2[1],NULL);
			get_symbol(vec2[0],(void **)&func);
			if (func)
			{
				list = g_list_prepend(list,(gpointer)func);
				list2 = g_list_prepend(list2,GINT_TO_POINTER(fps));
			}
			g_strfreev(vec2);
		}
		g_strfreev(vector);
		OBJ_SET_FULL(widget,"func_list",list,g_list_free);
		OBJ_SET_FULL(widget,"func_fps_list",list2,g_list_free);
	}

	/* If this widget has "initializer" there's a global variable 
	 * with it's name on it 
	 */
	if (cfg_read_string(cfgfile,section,"initializer",&initializer))
	{
		gint widget_type = 0;
		if (!cfg_read_string(cfgfile,section,"widget_type",&tmpbuf))
			MTXDBG(TABLOADER|CRITICAL,_("Object %s has initializer, but no widget_type!!!!\n"),section);
		else
			widget_type = translate_string(tmpbuf);
		g_free(tmpbuf);
		switch (widget_type)
		{
			case MTX_RANGE:
				gtk_range_set_value(GTK_RANGE(widget),(GINT)DATA_GET(global_data,initializer));
				break;

			case MTX_SPINBUTTON:
				gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),(GINT)DATA_GET(global_data,initializer));
				break;
			case MTX_ENTRY:
				gtk_entry_set_text(GTK_ENTRY(widget),(gchar *)DATA_GET(global_data,initializer));

			default:
				break;

		}
		g_free(initializer);
	}
	/* Hidden widgets have special handlers and should NOT be updated normally */
	cfg_read_boolean(cfgfile,section, "hidden", &hidden);
	offset = -1;
	cfg_read_int(cfgfile,section, "offset", &offset);
	if (offset >= 0 && indexed)
	{
		/*printf("indexed widget %s\n",name); */
		if (cfg_read_string(cfgfile, section, "size", &size))
		{
			offset += index * get_multiplier ((DataSize)translate_string (size));
			g_free(size);
		}
		else
		{
			if(OBJ_GET(widget, "size"))
			{
				offset += index * get_multiplier ((DataSize)(GINT)OBJ_GET(widget, "size"));
			}
			else
			{
				MTXDBG(TABLOADER|CRITICAL,_("Indexed Object %s has index and offset, but no size!!!!\n"),section);
				g_free(section);
				EXIT();
				return;
			}
		}
		/*printf("widget %s, offset %i\n",name,offset);*/
		OBJ_SET(widget,"offset",GINT_TO_POINTER(offset));
	}
	if (offset >= 0)
	{
		/* The way we do it now is to STORE widgets in LISTS for each
		 * offset, thus we can have multiple on screen controls bound
		 * to single data offset in the ECU
		 */
		if (page < 0)
		{
			MTXDBG(TABLOADER|CRITICAL,_("Attempting to append widget beyond bounds of Firmware Parameters,  there is a bug with this datamap widget %s, page %i, at offset %i...\n\n"),section,page,offset);
			g_free(section);
			EXIT();
			return;
		}
		if (page < firmware->total_pages)
		{
			if (offset >= firmware->page_params[page]->length)
				MTXDBG(TABLOADER|CRITICAL,_("Attempting to append widget beyond bounds of Firmware Parameters,  there is a bug with this datamap widget %s, at offset %i...\n\n"),section,offset);
			else if (!hidden)
			{

				tab_widgets = OBJ_GET(bindgroup->topframe,"tab_widgets");
				tab_widgets = g_list_prepend(tab_widgets, widget);
				OBJ_SET(bindgroup->topframe,"tab_widgets",tab_widgets);
				ecu_widgets[page][offset] = g_list_prepend(
						ecu_widgets[page][offset],
						(gpointer)widget);
			}
		}
		else
			MTXDBG(TABLOADER|CRITICAL,_("Attempting to append widget beyond bounds of Firmware Parameters, there is a bug with this datamap for widget %s, at page %i offset %i...\n\n"),section,page,offset);
	}

	/* If there is a "group" key in a section it means that it gets the
	 * rest of it's setting from the groupname listed.  This reduces
	 * redundant keys all throughout the file...
	 */
	bind_keys(G_OBJECT(widget), cfgfile, section, keys, num_keys);
	g_strfreev(keys);

	/* If this widget has the "choices" key (combobox)
	 */
	if (cfg_read_string(cfgfile,section,"choices",&tmpbuf))
	{
		combo_setup(G_OBJECT(widget),cfgfile,section);
		g_free(tmpbuf);
	}

	if (cfg_read_string(cfgfile,section,"post_functions_with_arg",&tmpbuf))
	{
		run_post_functions_with_arg(tmpbuf,widget);
		g_free(tmpbuf);
	}
	if (cfg_read_string(cfgfile,section,"post_functions",&tmpbuf))
	{
		run_post_functions(tmpbuf);
		g_free(tmpbuf);
	}
	if (cfg_read_boolean(cfgfile,section,"show_widget",&tmpi))
	{
		if (tmpi)
			gtk_widget_show(widget);
		else
			gtk_widget_hide(widget);
	}
	if (cfg_read_string(cfgfile,section,"set_tab_labels",&tmpbuf))
	{
		if (GTK_IS_NOTEBOOK(widget))
		{
			vector=g_strsplit(tmpbuf,",",-1);
			if (gtk_notebook_get_n_pages(GTK_NOTEBOOK(widget)) == g_strv_length(vector))
			{
				for (int i=0;i<g_strv_length(vector);i++)
				{
					gtk_notebook_set_tab_label_text(GTK_NOTEBOOK(widget),
							gtk_notebook_get_nth_page(GTK_NOTEBOOK(widget),i),
							vector[i]);
				}
			}
			g_strfreev(vector);
		}
		g_free(tmpbuf);
	}
	g_free(section);
	MTXDBG(TABLOADER,_("Leaving"));
	EXIT();
	return;
}
Exemplo n.º 3
0
/*!
 \brief gui_dispatcher() is a GTK+ timeout that runs 30 tiems per second checking
 for message on the dispatch queue which handles gui operations after a thread
 function runs, This will attempt to handle multiple messages at a time if the
 queue has multiple message queued up.
 \param data (gpointer) unused
 \returns TRUE 
 */
gboolean gui_dispatcher(gpointer data)
{
	gint len=0;
	gint i=0;
	UpdateFunction val = 0;
	gint count = 0;
	GtkWidget *widget = NULL;
	Io_Message *message = NULL;
	Text_Message *t_message = NULL;
	Widget_Update *w_update = NULL;
	QFunction *qfunc = NULL;
	extern volatile gboolean leaving;
	/*extern gint mem_view_style[];*/

	if (!gui_dispatch_queue) /*queue not built yet... */
	{
		g_cond_signal(gui_dispatch_cond);
		return TRUE;
	}
	/* Endless Loop, wait for message, processs and repeat... */
trypop:
	/*printf("gui_dispatch queue length is %i\n",g_async_queue_length(gui_dispatch_queue));*/
	if (leaving)
	{
		g_cond_signal(gui_dispatch_cond);
		return TRUE;
	}
	message = g_async_queue_try_pop(gui_dispatch_queue);
	if (!message)
	{
		/*	printf("no messages waiting, returning\n");*/
		g_cond_signal(gui_dispatch_cond);
		return TRUE;
	}

	if (message->functions != NULL)
	{
		len = message->functions->len;
		for (i=0;i<len;i++)
		{
			if (leaving)
			{
				dealloc_message(message);
				g_cond_signal(gui_dispatch_cond);
				return TRUE;
			}

			val = g_array_index(message->functions,UpdateFunction, i);
			/*printf("gui_dispatcher\n");*/
			switch ((UpdateFunction)val)
			{
				case UPD_LOGBAR:
					/*printf("logbar update\n");*/
					t_message = (Text_Message *)message->payload;
					gdk_threads_enter();
					update_logbar(t_message->view_name,t_message->tagname,t_message->msg,t_message->count,t_message->clear);
					gdk_threads_leave();
					dealloc_textmessage(t_message);
					message->payload = NULL;
					break;
				case UPD_RUN_FUNCTION:
					/*printf("run function\n");*/
					qfunc = (QFunction *)message->payload;
					gdk_threads_enter();
					run_post_functions(qfunc->func_name);
					gdk_threads_leave();
					dealloc_qfunction(qfunc);
					message->payload = NULL;
					break;

				case UPD_WIDGET:
					/*printf("widget update\n");*/
					widget = NULL;
					w_update = (Widget_Update *)message->payload;
					switch (w_update->type)
					{
						case MTX_ENTRY:
							/*printf("entry\n");*/
							if (NULL == (widget = lookup_widget(w_update->widget_name)))
								break;
							gdk_threads_enter();
							gtk_entry_set_text(GTK_ENTRY(widget),w_update->msg);
							gdk_threads_leave();
							break;
						case MTX_LABEL:
							/*printf("label\n");*/
							if (NULL == (widget = lookup_widget(w_update->widget_name)))
								break;
							gdk_threads_enter();
							gtk_label_set_text(GTK_LABEL(widget),w_update->msg);
							gdk_threads_leave();
							break;
						case MTX_TITLE:
							/*printf("title\n");*/
							gdk_threads_enter();
							set_title(g_strdup(w_update->msg));
							gdk_threads_leave();
							break;
						case MTX_SENSITIVE:
							/*printf("sensitivity change\n");*/
							if (NULL == (widget = lookup_widget(w_update->widget_name)))
								break;
							gdk_threads_enter();
							gtk_widget_set_sensitive(GTK_WIDGET(widget),w_update->state);
							gdk_threads_leave();
							break;
						default:
							break;
					}
					dealloc_w_update(w_update);
					message->payload = NULL;
					break;
					gdk_threads_enter();
					reset_temps(OBJ_GET(global_data,"temp_units"));
					gdk_threads_leave();
					/*
					   case UPD_RAW_MEMORY:
					   update_raw_memory_view(mem_view_style[message->offset],message->offset);
					   break;
					 */
			}

			gdk_threads_enter();
			while (gtk_events_pending())
			{
				if (leaving)
					goto dealloc;
				gtk_main_iteration();
			}
			gdk_threads_leave();
		}
	}
dealloc:
	dealloc_message(message);
	/*printf ("deallocation of dispatch message complete\n");*/
	count++;
	/* try to handle up to 4 messages at a time.  If this is 
	 * set too high, we can cause the timeout to hog the gui if it's
	 * too low, things can fall behind. (GL redraw ;( )
	 * */
	if ((count < 3) && (!leaving))
	{
		/*printf("trying to handle another message\n");*/
		goto trypop;
	}
	/*printf("returning\n");*/
	g_cond_signal(gui_dispatch_cond);
	return TRUE;
}