gtkextra
"Chuck Haines" <[email protected]>
| Newsgroups | gmane.comp.scigraphica.gtkextra |
|---|---|
| Message-ID | <[email protected]> |
Alright, I couldn't get gtkextra-2 to ./configure so I gave up on it and went back to gtkextra. I finally got it compiled and installed. However I've writted a program to use it and I'm getting the following error when I try and run the program: (dataread:5402): GLib-GObject-WARNING **: specified class size for type `GtkPlotCanvas' is smaller than the parent type's `GtkFixed' class size (dataread:5402): Gtk-CRITICAL **: file gtktypeutils.c: line 99 (gtk_type_new): assertion `GTK_TYPE_IS_OBJECT (type)' failed (dataread:5402): GLib-GObject-WARNING **: specified class size for type `GtkPlotCanvas' is smaller than the parent type's `GtkFixed' class size (dataread:5402): Gtk-WARNING **: invalid cast from (NULL) pointer to `(unknown)' Segmentation fault I'm running Slackware 9 with gtk+2. Any help would be much appreciated. I'm taking the code I'm using directly from the testrealtime.c demo that came with gtkextra. I've attached my sourcecode in case you need it. ==================================== Chuck Haines [email protected] http://www.linux-xtreme.net ==================================== WPI ECE Systems Administrator WPI Game Development Club Developer WPI Linux Association Lab Manager Tau Kappa Epsilon Fraternity TKE-IT Systems Administrator ==================================== AIM: CyberGrex YIM: CyberGrex_27 ICQ: 3707881 ====================================
dataread.c
(application/octet-stream, 20.8 KB)
/* dataread.c - Graphical frontend to DAQ-Card counter
* Author: Charles A. Haines
* Company: Bechtel Nevada
* Version: 0.51
*/
#include<stdio.h>
#include<gtk/gtk.h>
#include<gdk/gdk.h>
#include<comedilib.h>
#include<string.h>
#include<sys/time.h>
#include<unistd.h>
#include<gtkextra/gtkplot.h>
#include<gtkextra/gtkplotdata.h>
#include<gtkextra/gtkplotcanvas.h>
#include<string.h>
#include<malloc.h>
#include<math.h>
#include<stdlib.h>
/* The subdevice that is the counter on the card */
#define SUBDEVICE 4
/* Set to 1 for debug purposes */
#define DEBUG 1
/* Some global vars
* Only used for simplicity */
comedi_t *card; /* The comedi card */
lsampl_t data = 0; /* The value read from the counter */
/* user variables */
guint32 nUpdateGamma = 1000; /* Milliseconds to update gamma count */
guint32 nUpdateNeutron = 2000; /* Milliseconds to update neutron count */
guint32 nxAxisScale = 1; /* counts for x axis scale */
guint32 nyAxisScale = 1; /* seconds for y axis scale */
/* vars for timer interrupts */
guint nGammaTimer;
guint nNeutronTimer;
/* gtk defs */
GtkWidget *window;
GtkWidget *prefs;
GtkWidget *canvas;
GtkWidget *gammaCounts;
GtkWidget *neutronCounts;
GtkWidget *xAxis, *yAxis, *wgamma, *neutron;
/* function prototypes */
gint comedi_init(gpointer data);
int comedi_init_counter(comedi_t *dev, /* pointer to the comedi card */
int subd, /* which subdevice to init */
int chan, /* the channel to init */
int start /* the value to start the counter at */
);
gint comedi_get_gamma_counts (gpointer data);
gint comedi_get_neutron_counts (gpointer data);
GtkItemFactoryCallback change_prefs();
GtkItemFactoryCallback prog_quit();
GtkItemFactoryCallback prog_about();
void save_prefs(GtkWidget *widget, gpointer data);
void cancel_prefs(GtkWidget *widget, gpointer data);
/* gtk functions */
/* this function determines whether the user actually wants to exit or not */
gint delete_event(GtkWidget *widget,
GdkEvent *event,
gpointer data)
{
GtkWidget *exit;
exit = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
"Are you sure you want to quit?"
);
gint result = gtk_dialog_run(GTK_DIALOG(exit));
gtk_widget_destroy(exit);
switch (result)
{
case GTK_RESPONSE_YES:
/* They want to exit the program, so go ahead */
return FALSE;
break;
case GTK_RESPONSE_NO:
/* They were only kidding about exiting, so don't */
return TRUE;
break;
}
/* should never get here, this is just so gcc doesn't complain */
return 0;
}
/* this actually kills the program */
void destroy (GtkWidget *widget,
gpointer data)
{
gtk_main_quit();
}
/* returns a menubar widget made from the menu structure */
GtkWidget *get_menubar_menu(GtkWidget *window)
{
GtkItemFactory *item_factory;
GtkAccelGroup *accel_group;
/* create the menu structure */
static GtkItemFactoryEntry menu_items[] = {
{ "/_File", NULL, NULL, 0, "<Branch>" },
{ "/File/Preferences", "<CTRL>P", change_prefs, 1, "<Item>" },
{ "/File/sep", NULL, NULL, 0, "<Separator>" },
{ "/File/Exit", "<CTRL>X", prog_quit, 1, "<Item>" },
{ "/_Help", NULL, NULL, 0, "<Branch>" },
{ "/Help/About", "<CTRL>H", prog_about, 1, "<Item>" } };
static gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
/* make an accel group (shortcut keys) */
accel_group = gtk_accel_group_new();
/* make the menubar */
item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", accel_group);
/* generate the menu items */
gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL);
/* attach the new accelerator group to the window */
gtk_window_add_accel_group(GTK_WINDOW(window), accel_group);
/* finally return the actual menubar created */
return gtk_item_factory_get_widget(item_factory, "<main>");
}
/* start the main program */
int main (int argc, char *argv[])
{
/* gtk widgets */
GtkWidget *table;
GtkWidget *menubar, *canvas;
GdkColor color;
/* initialize any command line arguments */
gtk_init(&argc, &argv);
/* main gtk window */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* set the default window size to 240x320, the size of an iPAQ */
gtk_window_set_default_size(GTK_WINDOW(window), 240, 320);
gtk_container_border_width(GTK_CONTAINER(window), 0);
/* Set the window title */
gtk_window_set_title(GTK_WINDOW(window), "Janus");
/* set the signal handler to ask the user if they really want to quit when they press the X */
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_event), NULL);
/* set the signal handler that actually exits the program */
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
/* set the comedi_init function to be called during the gtk_main loop */
gtk_init_add(comedi_init, NULL);
/* add the timeouts to read from the counters */
/* first the gamma */
nGammaTimer = gtk_timeout_add (nUpdateGamma, /* interval to pull counts, user defined */
comedi_get_gamma_counts, /* function to call */
NULL
);
/* now the neutron */
nNeutronTimer = gtk_timeout_add (nUpdateNeutron, /* interval to pull counts, user defined */
comedi_get_neutron_counts, /* function to call */
NULL
);
/* init the table for layout purposes */
table = gtk_table_new(3, 2, FALSE);
/* put the table into the main window */
gtk_container_add(GTK_CONTAINER(window), table);
/* get the menu */
menubar = get_menubar_menu(window);
/* put it in the table for layout */
gtk_table_attach(GTK_TABLE(table), menubar, 0, 2, 0, 1, GTK_FILL, GTK_SHRINK, 0, 0);
/* now show it */
gtk_widget_show(menubar);
/* setup the canvas */
canvas = gtk_plot_canvas_new(240, 300, 1);
GTK_PLOT_CANVAS_UNSET_FLAGS(GTK_PLOT_CANVAS(canvas), GTK_PLOT_CANVAS_DND_FLAGS);
gtk_table_attach(GTK_TABLE(table), canvas, 0, 2, 1, 2, GTK_FILL, GTK_FILL, 0, 0);
gtk_widget_show(canvas);
/* setup the gamma counts */
gammaCounts = gtk_label_new("0\nGamma");
/* set the justification to center */
gtk_label_set_justify(GTK_LABEL(gammaCounts), GTK_JUSTIFY_CENTER);
/* underline the numbers */
/* gtk_label_set_pattern(GTK_LABEL(gammaCounts), "_"); */
/* attach the widget to the position in the table */
gtk_table_attach_defaults(GTK_TABLE(table), gammaCounts, 0, 1, 2, 3);
/* now show the widget */
gtk_widget_show(gammaCounts);
/* setup the neutron counts */
neutronCounts = gtk_label_new("0\nNeutron");
/* set the justifications to center */
gtk_label_set_justify(GTK_LABEL(neutronCounts), GTK_JUSTIFY_CENTER);
/* underline the numbers */
/* gtk_label_set_pattern(GTK_LABEL(neutronCounts), "_"); */
/* attach the widget to the position in the table */
gtk_table_attach_defaults(GTK_TABLE(table), neutronCounts, 1, 2, 2, 3);
/* now show the widget */
gtk_widget_show(neutronCounts);
/* show the widgets */
gtk_widget_show(table);
gtk_widget_show(window);
/* start the main gtk loop */
gtk_main();
/* exit gracefully */
return 0;
}
/* start functions */
/* This functions initializes the comedi device */
gint comedi_init(gpointer data)
{
/* open the comedi device */
int nError;
card = comedi_open("/dev/comedi0");
if(!card)
{
GtkWidget *error;
error = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
"There was an error opening your comedi card. Please make sure that the card is inserted and that the comedi modules are loaded.\n"
);
/* Display the error dialog until the user presses ok */
gtk_dialog_run(GTK_DIALOG(error));
/* Exit the program */
gtk_main_quit();
}
nError = comedi_lock(card, SUBDEVICE);
if (-1 == nError)
{
/* There was an error locking the card, shouldn't be a problem, but warn the user anyway */
GtkWidget *warn;
warn = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK,
"There was an error locking the comedi device. This might cause unexpected results\n"
);
gtk_dialog_run(GTK_DIALOG(warn));
gtk_widget_destroy(warn);
}
/* Initialize and start both counters */
comedi_init_counter(card, SUBDEVICE, 0, 0);
comedi_init_counter(card, SUBDEVICE, 1, 0);
return 0;
}
/* This function sets up the counter for use.
* An error number will be returned if there was any problem */
int comedi_init_counter(comedi_t *dev, int subd, int chan, int start)
{
/* Number of INSN steps to perform, don't change */
#define QD_NSTEPS 8
comedi_insnlist the_list;
comedi_insn test_insn[QD_NSTEPS];
lsampl_t darm_data[1];
lsampl_t op_data[2];
lsampl_t dir_data[2];
lsampl_t gate_data[2];
lsampl_t src_data[2];
lsampl_t wrt_data[1];
lsampl_t arm_data[1];
lsampl_t rst_data[1];
int ret, i;
/* Allocate memory */
memset(&test_insn, sizeof(test_insn), 0);
the_list.insns=test_insn;
the_list.n_insns=QD_NSTEPS;
/* Set each insn channel to the channel value passed
* and each subdevice to the subdevice value passed */
for(i=0; i<QD_NSTEPS; i++){
test_insn[i].chanspec = chan;
test_insn[i].subdev = subd;
}
/* First INSN config */
test_insn[0].insn = INSN_CONFIG;
test_insn[0].n = 1;
test_insn[0].data = darm_data;
/* Disarm the counter */
darm_data[0]=GPCT_DISARM;
test_insn[1].insn = INSN_CONFIG;
test_insn[1].n = 1;
test_insn[1].data = rst_data;
/* Reset the counter */
rst_data[0]=GPCT_RESET;
test_insn[2].insn = INSN_CONFIG;
test_insn[2].n = 2;
test_insn[2].data = gate_data;
gate_data[0]=GPCT_SET_GATE;
/* Don't latch the counter to the GPCT gate */
gate_data[1]=GPCT_NO_GATE;
test_insn[3].insn = INSN_CONFIG;
test_insn[3].n = 2;
test_insn[3].data = src_data;
src_data[0]=GPCT_SET_SOURCE;
/* Set the counter to pull from GPCTi_SOURCE */
src_data[1]=GPCT_EXT_PIN;
test_insn[4].insn = INSN_WRITE;
test_insn[4].n = 1;
test_insn[4].data = wrt_data;
/* Start the counter at the value passed to the function */
wrt_data[0]=start;
test_insn[5].insn = INSN_CONFIG;
test_insn[5].n = 2;
test_insn[5].data = op_data;
op_data[0]=GPCT_SET_OPERATION;
/* Simple counter, no buffering */
op_data[1]=GPCT_SIMPLE_EVENT;
test_insn[6].insn = INSN_CONFIG;
test_insn[6].n = 2;
test_insn[6].data = dir_data;
dir_data[0]=GPCT_SET_DIRECTION;
/* Increment the counter on each positive (1) */
dir_data[1]=GPCT_HWUD;
test_insn[7].insn = INSN_CONFIG;
test_insn[7].n = 1;
test_insn[7].data = arm_data;
/* Arm the counter */
arm_data[0] = GPCT_ARM;
/* Send all the configurations to the card */
ret=comedi_do_insnlist(dev,&the_list);
/* return to main program */
return ret;
}
/* this function pulls the gamma counts, plots them and then resets the counter */
gint comedi_get_gamma_counts (gpointer data)
{
comedi_data_read(card, SUBDEVICE, 0, 0, 0, &data);
comedi_init_counter(card, SUBDEVICE, 0, 0);
char *str;
str = malloc(sizeof(data) + sizeof("\nGamma"));
if(str != NULL)
{
sprintf(str, "%d\n%s", (lsampl_t)data, "Gamma");
gtk_label_set_text(GTK_LABEL(gammaCounts), str);
free(str);
}
return 1;
}
/* this function pulls the neutron counts, plots them and then resets the counter */
gint comedi_get_neutron_counts (gpointer data)
{
comedi_data_read(card, SUBDEVICE, 1, 0, 0, &data);
comedi_init_counter(card, SUBDEVICE, 1, 0);
char *str;
str = malloc(sizeof(data) + sizeof("\nNeutron"));
if(str != NULL)
{
sprintf(str, "%d\n%s", (lsampl_t)data, "Neutron");
gtk_label_set_text(GTK_LABEL(neutronCounts), str);
free(str);
}
return 1;
}
/* Change user preferences */
GtkItemFactoryCallback change_prefs()
{
GtkWidget *table, *label, *button, *separator, *hbox;
/* create the preferences window */
prefs = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* set the window title */
gtk_window_set_title(GTK_WINDOW(prefs), "Janus Preference");
/* set the default size */
gtk_window_set_default_size(GTK_WINDOW(prefs), 240, 175);
/* set the parent window */
gtk_window_set_transient_for(GTK_WINDOW(prefs), GTK_WINDOW(window));
/* set the window to modal */
gtk_window_set_modal(GTK_WINDOW(prefs), TRUE);
/* make sure prefs is destroyed with the parent */
gtk_window_set_destroy_with_parent(GTK_WINDOW(prefs), TRUE);
/* set up the table for layout purposes */
table = gtk_table_new(6, 2, FALSE);
/* add the table to the toplevel window */
gtk_container_add(GTK_CONTAINER(prefs), table);
/* start the preferences window */
label = gtk_label_new("Janus Preferences\n");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
gtk_table_attach(GTK_TABLE(table), label, 0, 2, 0, 1, GTK_EXPAND, GTK_SHRINK, 0, 0);
gtk_widget_show(label);
/* create entry to change x-axis range */
xAxis = gtk_spin_button_new_with_range(1, 1000, 1);
/* attach it to the table */
gtk_table_attach(GTK_TABLE(table), xAxis, 0, 1, 1, 2, GTK_SHRINK, GTK_FILL, 0, 0);
/* set the initial value to whatever the current x-axis scale is */
gtk_spin_button_set_value(GTK_SPIN_BUTTON(xAxis), nxAxisScale);
/* finally show the widget */
gtk_widget_show(xAxis);
label = gtk_label_new("Counts (x-axis scale)");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 1, 2, GTK_SHRINK, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* create entry to change y-axis scale */
yAxis = gtk_spin_button_new_with_range(1, 120, 1);
/* attach it to the table */
gtk_table_attach(GTK_TABLE(table), yAxis, 0, 1, 2, 3, GTK_SHRINK, GTK_FILL, 0, 0);
/* set the initial value to whatever current y-axis sxale is */
gtk_spin_button_set_value(GTK_SPIN_BUTTON(yAxis), nyAxisScale);
/* show the widget */
gtk_widget_show(yAxis);
label = gtk_label_new("Sec(s) (y-axis scale)");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 2, 3, GTK_SHRINK, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* create entry to change secs to pull gamma counts */
wgamma = gtk_spin_button_new_with_range(1, 120, 1);
/* attach it to the table */
gtk_table_attach(GTK_TABLE(table), wgamma, 0, 1, 3, 4, GTK_SHRINK, GTK_FILL, 0, 0);
/* set the initial value */
gtk_spin_button_set_value(GTK_SPIN_BUTTON(wgamma), nUpdateGamma / 1000);
/* show the widget */
gtk_widget_show(wgamma);
label = gtk_label_new("Sec(s) to pull gamma counts");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 3, 4, GTK_SHRINK, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* create entry to change secs to pull neutron */
neutron = gtk_spin_button_new_with_range(1, 120, 1);
/* attach it to the table */
gtk_table_attach(GTK_TABLE(table), neutron, 0, 1, 4, 5, GTK_SHRINK, GTK_FILL, 0, 0);
/* set the initial value */
gtk_spin_button_set_value(GTK_SPIN_BUTTON(neutron), nUpdateNeutron / 1000);
/* show the widget */
gtk_widget_show(neutron);
label = gtk_label_new("Sec(s) to pull neutron counts");
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT);
gtk_table_attach(GTK_TABLE(table), label, 1, 2, 4, 5, GTK_SHRINK, GTK_FILL, 0, 0);
gtk_widget_show(label);
/* create separation between buttons and text */
separator = gtk_hseparator_new();
gtk_table_attach(GTK_TABLE(table), separator, 0, 2, 5, 6, GTK_FILL, GTK_FILL, 0, 10);
gtk_widget_show(separator);
/* create a hbox for layout purposes */
hbox = gtk_hbox_new(TRUE, 5);
gtk_table_attach(GTK_TABLE(table), hbox, 0, 2, 6, 7, GTK_FILL, GTK_FILL, 0, 0);
button = gtk_button_new_from_stock(GTK_STOCK_OK);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(save_prefs), NULL);
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 0);
gtk_widget_show(button);
button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(cancel_prefs), NULL);
gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, TRUE, 5);
gtk_widget_show(button);
gtk_widget_show_all(prefs);
return 0;
}
/* Make sure the user wants to quit */
GtkItemFactoryCallback prog_quit()
{
GtkWidget *exit;
exit = gtk_message_dialog_new(GTK_WINDOW(window),
GTK_DIALOG_MODAL,
GTK_MESSAGE_QUESTION,
GTK_BUTTONS_YES_NO,
"Are you sure you want to quit?"
);
gint result = gtk_dialog_run(GTK_DIALOG(exit));
gtk_widget_destroy(exit);
switch (result)
{
case GTK_RESPONSE_YES:
/* They want to exit the program, so go ahead */
gtk_main_quit();
break;
case GTK_RESPONSE_NO:
/* They were only kidding about exiting, so don't */
return 0;
break;
}
/* should never get here, this is just so gcc doesn't complain */
return 0;
}
GtkItemFactoryCallback prog_about()
{
GtkWidget *about, *label, *icon;
/* create the about dialog */
about = gtk_dialog_new_with_buttons("About Janus",
GTK_WINDOW(window),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK,
GTK_RESPONSE_ACCEPT,
NULL);
label = gtk_label_new("\nJanus v. 0.51\nAuthor: Charles A. Haines\nEmail: [email protected]\nCompany: Bechtel Nevada\n");
/* Create the help icon */
icon = gtk_image_new_from_file("janus.jpeg");
/* Ensure the widget is destroy on button press */
g_signal_connect_swapped(GTK_OBJECT(about), "response", G_CALLBACK(gtk_widget_destroy), GTK_OBJECT(about));
/* add the label to the about dialog */
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(about)->vbox), icon);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(about)->vbox), label);
/* show the widget */
gtk_widget_show_all(about);
return 0;
}
/* this function saves the user preferences and then destroy's the preferences window */
void save_prefs(GtkWidget *widget, gpointer data)
{
/* determine if either of the timer's need to be reset */
if ((nUpdateGamma / 1000) != gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wgamma)))
{
/* the gamma timer needs to be updated */
nUpdateGamma = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(wgamma));
/* change it to milliseconds */
nUpdateGamma *= 1000;
/* remove the timer */
gtk_timeout_remove(nGammaTimer);
/* now add the timer again with the correct interval */
nGammaTimer = gtk_timeout_add(nUpdateGamma, comedi_get_gamma_counts, NULL);
}
if ((nUpdateGamma / 1000) != gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(neutron)))
{
/* the neutron timer needs to be updated */
nUpdateNeutron = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(neutron));
/* change it to milliseconds */
nUpdateNeutron *= 1000;
/* remove the timer */
gtk_timeout_remove(nNeutronTimer);
/* now add the timer again with the correct interval */
nNeutronTimer = gtk_timeout_add(nUpdateNeutron, comedi_get_neutron_counts, NULL);
}
/* update the x and y axis scales */
nxAxisScale = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(xAxis));
nyAxisScale = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(yAxis));
/* update the data */
gtk_widget_destroy(prefs);
}
/* this cancel's the user preferences dialog */
void cancel_prefs(GtkWidget *widget, gpointer data)
{
gtk_widget_destroy(prefs);
}