Hi there and thanks for your time,
Problem(s): To pass single-values and arrays between functions in seperate source files without using extern global definitions, or writing then reading to and from an intermediate text file.
I’m using GTK+3. on Ubuntu 18.04.1 LTS with C language. A simplified version of my app is provided to show the problem, it consists of three c-source code files : 1) simplified.c (with main()), 2) callback_drawing1.c & 3) callback_drawing2.c, as well as the header file globals.h, Makefile and simplified.ui. The (simplified) app uses 4 SpinButtons (simplified.ui and associated callbacks in simplified.c) to define 2 points to which a straight line equation is fitted and drawn (in callback_drawing1.c) and the resulting array is then transferred to a function in another file (callback_drawing2.c) by writing to, then reading from, an intermediate text file.
In order to facilitate efficient use of my app on a web-server (to avoid name-clashes and writing to the hard-drive) I don’t want to use global definitions and writing/reading files to transfer data between functions, as they are at present, but haven’t yet succeeded in doing this as everything is done by the gtk_builder in the activate() function, and that has so far proved to be rather opaque. I have tried passing the values as arguments to the drawing functions (with and without) using return values in the SpinButton callbacks, as well as various other builder functions, and coded g_signal_connect() in activate(). It compiles but the values aren’t passed. What am I missing here, what do I need to do? Is the problem(s) one of C-programming or of GTK+ ? Should I unpack the contents of activate() back into main() and re-code ‘by hand’ rather than with builder.ui (big job!)?
Roger.
/*Start of globals.h *************************************************************/
float x1_line = 200.0;
float y1_line = 200.0;
float x2_line = 600.0;
float y2_line = 600.0;
/*End of globals.h *************************************************************/
/*Start of simplified.c *** contains main() *****************************************/
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include "globals.h"
/**********************/
void callback_x1_line (GtkSpinButton *spin_button, GtkBuilder *builder)
{
GtkWidget *drawing_area1;
int x_da;
int y_da;
extern float x1_line;
x1_line = gtk_spin_button_get_value (spin_button);
drawing_area1 = (GtkWidget*) gtk_builder_get_object (builder, "drawing_area1");
gtk_widget_get_size_request (drawing_area1, &x_da, &y_da);
gtk_widget_set_size_request (drawing_area1, x_da, y_da);
gtk_widget_queue_resize (drawing_area1);
}
/**********************/
void callback_y1_line (GtkSpinButton *spin_button, GtkBuilder *builder)
{
GtkWidget *drawing_area1;
int x_da;
int y_da;
extern float y1_line;
y1_line = gtk_spin_button_get_value (spin_button);
drawing_area1 = (GtkWidget*) gtk_builder_get_object (builder, "drawing_area1");
gtk_widget_get_size_request (drawing_area1, &x_da, &y_da);
gtk_widget_set_size_request (drawing_area1, x_da, y_da);
gtk_widget_queue_resize (drawing_area1);
}
/**********************/
void callback_x2_line (GtkSpinButton *spin_button, GtkBuilder *builder)
{
GtkWidget *drawing_area1;
int x_da;
int y_da;
extern float x2_line;
x2_line = gtk_spin_button_get_value (spin_button);
drawing_area1 = (GtkWidget*) gtk_builder_get_object (builder, "drawing_area1");
gtk_widget_get_size_request (drawing_area1, &x_da, &y_da);
gtk_widget_set_size_request (drawing_area1, x_da, y_da);
gtk_widget_queue_resize (drawing_area1);
}
/**********************/
void callback_y2_line (GtkSpinButton *spin_button, GtkBuilder *builder)
{
GtkWidget *drawing_area1;
int x_da;
int y_da;
extern float y2_line;
y2_line = gtk_spin_button_get_value (spin_button);
drawing_area1 = (GtkWidget*) gtk_builder_get_object (builder, "drawing_area1");
gtk_widget_get_size_request (drawing_area1, &x_da, &y_da);
gtk_widget_set_size_request (drawing_area1, x_da, y_da);
gtk_widget_queue_resize (drawing_area1);
}
/**********************/
GdkPixbuf *create_pixbuf1(const gchar * filename)
{
GdkPixbuf *pixbuf1;
GError *error = NULL;
pixbuf1 = gdk_pixbuf_new_from_file(filename, &error);
if(!pixbuf1)
{
fprintf(stderr, "%s\n", error->message);
g_error_free(error);
}
return pixbuf1;
}
/**********************/
static void
activate (GtkApplication *app, gpointer user_data)
{
int argc;
char **argv;
GtkBuilder *builder;
GtkWidget *window;
gtk_init (&argc, &argv);
builder = gtk_builder_new_from_file ("simplified.ui");
gtk_builder_connect_signals (builder, builder);
window = (GtkWidget *) gtk_builder_get_object (builder, "window");
gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf1("simplified.png"));
gtk_widget_show (window);
gtk_main ();
return;
}/*End of activate()*/
/**********************/
int main (int argc, char **argv)
{
struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY};
setrlimit(RLIMIT_STACK, &rlim);
GtkApplication *app;
int status;
app = gtk_application_new ("roger.simplified", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (activate), NULL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return status;
}/*End of main()*/
/*End of simplified.c *************************************************************/
/*Start of callback_drawing1.c *****************************************************/
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
gboolean callback_drawing1 (GtkWidget *widget, cairo_t *cr)
{
int x_da;
int y_da;
GdkRGBA color;
GtkStyleContext *context;
extern float x1_line, y1_line, x2_line, y2_line;
int i;
context = gtk_widget_get_style_context (widget);
x_da = gtk_widget_get_allocated_width (widget);
y_da = gtk_widget_get_allocated_height (widget);
gtk_render_background (context, cr, 0, 0, x_da, y_da);
cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
cairo_paint(cr);
cairo_set_source_rgba(cr, 0.6, 0, 0, 1.0);
cairo_set_line_width(cr, 5.0);
cairo_move_to(cr, x1_line, y1_line);
cairo_line_to(cr, x2_line, y2_line);
cairo_stroke(cr);
double line_slope[1001];
for (i=0; i<=1000; i++)
{
line_slope[i] = (y2_line-y1_line)/(x2_line-x1_line);
}
double line_yintercept[1001];
for (i=0; i<=1000; i++)
{
line_yintercept[i] = y2_line-line_slope[i]*x2_line;
}
double line[1001];
for (i=0; i<=1000; i++)
{
line[i] = (line_slope[i]*(double)i)+line_yintercept[i];
}
FILE* outfile_line = fopen("file_line", "w");
for (i=0; i<=1000; i++)
{
fprintf(outfile_line,"%f\n", line[i]);
}
fclose(outfile_line);
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_set_line_width(cr, 1.0);
cairo_move_to(cr, 0, line[0]);
for (i=0; i<=1000; i++)
{
cairo_line_to(cr, i, line[i]);
}
cairo_stroke(cr);
return FALSE;
}
/*End of callback_drawing1.c ******************************************************/
/*Start of callback_drawing2.c ******************************************************/
#include <stdio.h>
#include <math.h>
#include <errno.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>
gboolean callback_drawing2 (GtkWidget *widget, cairo_t *cr)
{
int x_da;
int y_da;
GdkRGBA color;
GtkStyleContext *context;
extern float x1_line, y1_line, x2_line, y2_line;
int i;
context = gtk_widget_get_style_context (widget);
x_da = gtk_widget_get_allocated_width (widget);
y_da = gtk_widget_get_allocated_height (widget);
gtk_render_background (context, cr, 0, 0, x_da, y_da);
cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
cairo_paint(cr);
double line[1001];
FILE* infile_line = fopen("file_line", "r");
for (i=0; i<=1000; i++)
{
fscanf(infile_line,"%lf\n", &line[i]);
}
fclose(infile_line);
cairo_set_source_rgba(cr, 0, 0, 0, 0.5);
cairo_set_line_width(cr, 1.0);
cairo_move_to(cr, 0, line[0]);
for (i=0; i<=1000; i++)
{
cairo_line_to(cr, i, line[i]);
}
cairo_stroke(cr);
return FALSE;
}
/*End of callback_drawing2.c ******************************************************/
/*Start of Makefile ***************************************************************/
CC = gcc
CFLAGS = `pkg-config --cflags gtk+-3.0`
CPPFLAGS = -mcmodel=large -rdynamic
LIBS = `pkg-config --libs gtk+-3.0` -lm
all: simplified
simplified: simplified.o callback_drawing1.o callback_drawing2.o
$(CC) $(CPPFLAGS) $(CFLAGS) -o simplified simplified.o callback_drawing1.o callback_drawing2.o $(LIBS)
clean:
rm -f simplified
rm -f *.o
.PHONY: all clean
/*End of Makefile ***************************************************************/
/*Start of simplified.ui ************************************************************/
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkAdjustment" id="adjustment_y_da">
<property name="upper">620</property>
<property name="lower">100</property>
<property name="value">484</property>
<property name="step_increment">2</property>
<property name="page_increment">2</property>
</object>
<object class="GtkAdjustment" id="adjustment_scrolledwindow">
<property name="upper">800</property>
<property name="lower">0</property>
<property name="value">300</property>
<property name="step_increment">1</property>
<property name="page_increment">1</property>
</object>
<object class="GtkAdjustment" id="adjustment_x1_line">
<property name="upper">500.0</property>
<property name="lower">0.0</property>
<property name="value">200.0</property>
<property name="step_increment">1.0</property>
<property name="page_increment">1.0</property>
</object>
<object class="GtkAdjustment" id="adjustment_y1_line">
<property name="upper">1001.0</property>
<property name="lower">0.0</property>
<property name="value">200.0</property>
<property name="step_increment">1.0</property>
<property name="page_increment">1.0</property>
</object>
<object class="GtkAdjustment" id="adjustment_x2_line">
<property name="upper">1001.0</property>
<property name="lower">501.0</property>
<property name="value">600.0</property>
<property name="step_increment">1.0</property>
<property name="page_increment">1.0</property>
</object>
<object class="GtkAdjustment" id="adjustment_y2_line">
<property name="upper">1001.0</property>
<property name="lower">0.0</property>
<property name="value">600.0</property>
<property name="step_increment">1.0</property>
<property name="page_increment">1.0</property>
</object>
<object class="GtkAdjustment" id="adjustment_scrolledwindow2">
<property name="upper">800</property>
<property name="lower">0</property>
<property name="value">300</property>
<property name="step_increment">1</property>
<property name="page_increment">1</property>
</object>
<object class="GtkWindow" id="window">
<property name="title">Simplified App</property>
<property name="can_focus">False</property>
<property name="default_width">1200</property>
<property name="default_height">720</property>
<signal name="delete-event" handler="gtk_main_quit" swapped="no"/>
<child>
<object id="notebook" class="GtkNotebook">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkBox" id="box1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow_type">in</property>
<property name="vadjustment">adjustment_scrolledwindow</property>
<child>
<object class="GtkViewport" id="viewport">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkDrawingArea" id="drawing_area1">
<property name="width_request">4000</property>
<property name="height_request">800</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<signal name="draw" handler="callback_drawing1" swapped="no"/>
</object>
</child> <!--drawing_area -->
</object>
</child> <!--viewport_line -->
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> <!--scrolledwindow_line -->
<child>
<object class="GtkBox" id="box2_line">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButtonBox" id="buttonbox1_line">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkLabel" id="label_x1_line">
<property name="label">x1</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_y1_line">
<property name="label">y1</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_x2_line">
<property name="label">x2</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_y2_line">
<property name="label" >y2</property>
<property name="visible">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child> <!--buttonbox1_line -->
<child>
<object class="GtkButtonBox" id="buttonbox2_line">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">spread</property>
<child>
<object class="GtkSpinButton" id="spin_x1_line">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="numeric">True</property>
<property name="snap-to-ticks">True</property>
<property name="progress_pulse_step">1</property>
<property name="adjustment">adjustment_x1_line</property>
<property name="climb_rate">1.0</property>
<property name="value">200.0</property>
<signal name="value-changed" handler="callback_x1_line" swapped="no"/>
<signal name="scroll-event" handler="gtk_true" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child> <!--spin_x1_line -->
<child>
<object class="GtkSpinButton" id="spin_y1_line">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="numeric">True</property>
<property name="snap-to-ticks">True</property>
<property name="progress_pulse_step">1</property>
<property name="adjustment">adjustment_y1_line</property>
<property name="climb_rate">1.0</property>
<property name="value">200.0</property>
<signal name="value-changed" handler="callback_y1_line" swapped="no"/>
<signal name="scroll-event" handler="gtk_true" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> <!--spin_y1_line -->
<child>
<object class="GtkSpinButton" id="spin_x2_line">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="numeric">True</property>
<property name="snap-to-ticks">True</property>
<property name="progress_pulse_step">1</property>
<property name="adjustment">adjustment_x2_line</property>
<property name="climb_rate">1.0</property>
<property name="value">600.0</property>
<signal name="value-changed" handler="callback_x2_line" swapped="no"/>
<signal name="scroll-event" handler="gtk_true" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child> <!--spin_x2_line -->
<child>
<object class="GtkSpinButton" id="spin_y2_line">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="numeric">True</property>
<property name="snap-to-ticks">True</property>
<property name="progress_pulse_step">1</property>
<property name="adjustment">adjustment_y2_line</property>
<property name="climb_rate">1.0</property>
<property name="value">600.0</property>
<signal name="value-changed" handler="callback_y2_line" swapped="no"/>
<signal name="scroll-event" handler="gtk_true" swapped="no"/>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">6</property>
</packing>
</child> <!--spin_y2_line -->
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child> <!--buttonbox2_line -->
</object>
</child> <!--box2_line -->
</object>
</child> <!--box1 -->
<child type="tab">
<object class="GtkLabel" id="tab1">
<property name="label">Page1</property>
</object>
</child> <!--tab1 -->
<child>
<object class="GtkBox" id="box2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow_type">in</property>
<property name="vadjustment">adjustment_scrolledwindow2</property>
<child>
<object class="GtkViewport" id="viewport2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkDrawingArea" id="drawing_area2">
<property name="width_request">4000</property>
<property name="height_request">800</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="valign">start</property>
<signal name="draw" handler="callback_drawing2" swapped="no"/>
</object>
</child> <!--drawing_area2 -->
</object>
</child> <!--viewport2 -->
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child> <!--scrolledwindow2 -->
</object>
</child> <!--box2 -->
<child type="tab">
<object class="GtkLabel" id="tab2">
<property name="label">Page2</property>
</object>
</child> <!--tab2 -->
</object>
</child> <!--notebook -->
<child type="titlebar">
<placeholder/>
</child> <!--window -->
</object>
</interface>
/*End of simplified.ui ************************************************************/