'GtkToggleButton {aka struct _GtkTogglebutton}' has no member 'active' - c

I am trying to compile and run an example of gtk+3, unfortunately, the example is from gtk+2 manual, I can't find anything useful on gtk+3 and I can't download gtk+2.
On the example there are a couple of function like this:
void entry_toggle_editable( GtkWidget *checkbutton,
GtkWidget *entry )
{
gtk_editable_set_editable(GTK_EDITABLE(entry),GTK_TOGGLE_BUTTON(checkbutton)->active);
}
When compiling I got this error:
'GtkToggleButton {aka struct _GtkToggleButton}' has no member named 'active'
I looked in all manuals. I was able to find in order to get around the problem, I understand that probably it is a release compatibility problem, but gtk+3 manuals are really useless for somebody approaching for the first time Gtk.

One of the biggest changes between GTK+ 2 and GTK+ 3 is that GTK+ 3 gets rid of all public structure fields, replacing them with GObject properties. So instead of saying
GTK_TOGGLE_BUTTON(checkbutton)->active
you say
gboolean active;
g_object_get(checkbutton, "active", &active, NULL);
(The NULL is because g_object_get() can get multiple properties from the same object at the same time; the NULL says "that is all I need from this call".)
GTK+ also provides accessor methods to add type checking, so you can also say
gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton))
Using these when available is preferable to calling g_object_get() directly.
The GTK+ documentation does come with a tutorial. As you probably realized, you cannot use GTK+ 2 examples to learn GTK+ 3 without modification; you will need to spend more time finding GTK+ 3 examples.

Related

Gtk::Widget missing set_visual() method in gtkmm-3.0

As seen in the Gtk documentation here there is a method to set the visual of the Widget which seems to be missing from gtkmm (C++ wrapper).
While trying to port a Gtk application from C to C++ using gtkmm-3.0, quickly discovered that the set_visual() method is missing. Although there is a get_visual() that returns the visual of the widget.
The C code looks like this:
GdkScreen *screen = gtk_widget_get_screen(widget);
GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
if (visual == NULL)
visual = gdk_screen_get_system_visual(screen);
gtk_widget_set_visual(widget, visual);
Does anyone know how can i set the widget visual with a custom one?
If the C++ wrapper does not provide what you need, you can always get a pointer to the underlying C GObject instance and work with it as you would in a typical GTK C application. Check out this method for Gtk::Widget:
GtkWidget* Gtk::Widget::gobj()
So you can call this on your widget, get a C GtkWidget pointer and call gtk_widget_set_visual on it like you are doing in your question. Note that this solution works all across Gtkmm, which in my opinion is a really nice feature that other wrappers do not have.

How to design generic backward compatible API for embedded software application library interface in C?

I am tasked to assist with the design of a dynamic library (exposed with a C interface) aimed to be used in embed software application on various embed platform (Android,Windows,Linux).
Main requirements are speed , and decoupling.
For the decoupling part : one of our requirement is to be able to facilitate integration and so permit backward compatibility and resilience.
My library have some entry points that should be called by the integrating software (like an initialize constructor to provide options as where to log, how to behave etc...) and could also call some callback in the application (an event to inform when task is finished).
So I have come with several propositions but as each of one not seems great I am searching advice on a better or standard ways to achieve decoupling an d backward compatibility than this 3 ways that I have come up :
First an option that I could think of is to have a generic interface call for my exposed entry points for example with a hashmap of key/values for the parameters of my functions so in pseudo code it gives something like :
myLib.Initialize(Key_Value_Option_Array_Here);
Another option is to provide a generic function to provide all the options to the library :
myLib.SetOption(Key_Of_Option, Value_OfOption);
myLib.SetCallBack(Key_Of_Callbak, FunctionPointer);
When presenting my option my collegue asked me why not use a google protobuf argument as interface between the library and the embed software : but it seems weird to me, as their will be a performance hit on each call for serialization and deserialization.
Are there any more efficient or standard way that you coud think of?
You could have a struct for optional arguments:
typedef struct {
uint8_t optArg1;
float optArg2;
} MyLib_InitOptArgs_T;
void MyLib_Init(int16_t arg1, uint32_t arg2, MyLib_InitOptArgs_T const * optionalArgs);
Then you could use compound literals on function call:
MyLib_Init(1, 2, &(MyLib_InitOptArgs_T){ .optArg2=1.2f });
All non-specified values would have zero-ish value (0, NULL, NaN), and would be considered unused. Similarly, when passing NULL for struct pointer, all optional arguments would be considered unused.
Downside with this method is that if you expect to have many new arguments in the future, structure could grow too big. But whether that is an issue, depends on what your limits are.
Another option is to simply have multiple smaller initialization functions for initializating different subsystems. This could be combined with the optional arguments system above.

GtkAlignment can only contain one widget at a time

I made a GUI in Glade. I have this kind of structure:
_ A GtkWindow named winTimer
__ A GtkVBox
___ A GtkHBox
____ A GtkAlignment called alignTimer with absolutely nothing inside.
My structure (gif)
I do:
controlli->alignTimer=GTK_WIDGET(gtk_builder_get_object(builder,"alignTimer"));
controlli->pbTimerComposito = gdk_pixbuf_new(GDK_COLORSPACE_RGB,0,8,320,200);
controlli->imgTimer = GTK_WIDGET(gtk_image_new_from_pixbuf(controlli->pbTimerComposito));
gtk_container_add(GTK_CONTAINER(controlli->alignTimer),controlli->imgTimer); /* warning */
gtk_widget_show(controlli->imgTimer);
Where controlli is a pointer to a struct that has, among other things:
GtkWidget *alignTimer;
GdkPixbuf *pbTimerComposito;
GtkWidget *imgTimer;
I get this at runtime:
Gtk-WARNING **: Attempting to add a widget with type GtkImage to a GtkAlignment, but as a GtkBin subclass a GtkAlignment can only contain one widget at a time; it already contains
a widget of type GtkImage
But that is not true! It's the first and only widget that I'm adding! What's happening? I had done the exact same thing in another part of my app and it's been working perfectly for years.
My environment:
- Windows XP SP3
- MinGW
- GCC 4.8.1
- GTK 2.24.10
PS I know I'm using an old version of GTK, deprecated widgets and an ancient OS, but I code just for fun so I'm OK with that. Any help will be very appreciated.
Problem solved (or, rather, there was no problem).
The function that contained the code I posted above was called twice. Facepalm for myself.

How would I go about getting text entry from Glade in GTK?

I am working on trying to get Text input from my text entry fields to an array. I have 8 text entry fields and have been following many of the tutorials. So far from what I gathered . I have
void on_Save_and_Process_button_clicked(GTKButton *button, GtkEntry *text){
GTKWidget *entry1 = lookup_widget(text,"entry1");
Const g char *entry_text1 = gtk_entry _get_text(GTK_ENTRY(entry1));
}
I am getting an warning in:
GTKWidget *entry1 = lookup_widget(text,"entry1");
That says:
warning: intialization make pointer from integer without a cast
This my first GTK project. Any help,guidance, links to tutorials of similar projects would be much appreciated.
The function lookup_widget was part of Glade 2, a long time ago. Back then, Glade would generate C code, instead of an XML file, and that function was included in the generated code.
You can't even run Glade 2 anymore most likely, so the tutorial you are using is not going to help you very much. Use a more modern tutorial, such as the one included in the official GTK 3.x documentation.

Initializing private data in custom Gtk+ widget which depends on parent's members (C)

I'm working on a pet project solely for the purpose of learning a few API's. It's not intended to have practical value, but rather to be relatively simple excercise to get me comfortable with libpcap, gtk+, and cairo before I use them for anything serious. This is a graphical program, implemented in C and using Gtk+ 2.x. It's eventually going to read frames with pcap (currently I just have a hardcoded test frame), then use cairo to generate pretty pictures using color values generated from the raw packet (at this stage, I'm just using cairo_show_text to print a text representation of the frame or packet). The pictures will then be drawn to a custom widget inheriting from GtkDrawingArea.
My first step, of course, is to get a decent grasp of the Gtk+ runtime environment so I can implement my widget. I've already managed to render and draw text using cairo to my custom widget. Now I'm at the point where I think the widget really needs private storage for things like the cairo_t context pointer and a GdkRegion pointer (I had not planned to use Gdk directly, but my research indicates that it may be necessary in order to call gdk_window_invalidate_region() to force my DrawingArea to refresh once I've drawn a frame, not to mention gdk_cairo_create()). I've set up private storage as a global variable (the horror! Apparently this is conventional for Gtk+. I'm still not sure how this will even work if I have multiple instances of my widget, so maybe I'm not doing this part right. Or maybe the preprocessor macros and runtime environment are doing some magic to give each instance its own copy of this struct?):
/* private data */
typedef struct _CandyDrawPanePrivate CandyDrawPanePrivate;
struct _CandyDrawPanePrivate {
cairo_t *cr;
GdkRegion *region;
};
#define CANDY_DRAW_PANE_GET_PRIVATE(obj)\
(G_TYPE_INSTANCE_GET_PRIVATE((obj), CANDY_DRAW_PANE_TYPE, CandyDrawPanePrivate))
Here's my question: Initializing the pointers in my private data struct depends on members inherited from the parent, GtkWidget:
/* instance initializer */
static void candy_draw_pane_init(CandyDrawPane *pane) {
GdkWindow *win = NULL;
/*win = gtk_widget_get_window((GtkWidget *)pane);*/
win = ((GtkWidget*)pane)->window;
if (!win)
return;
/* TODO: I should probably also check this return value */
CandyDrawPanePrivate *priv = CANDY_DRAW_PANE_GET_PRIVATE(((CandyDrawPane*)pane));
priv->cr = gdk_cairo_create(win);
priv->region = gdk_drawable_get_clip_region(win);
candy_draw_pane_update(pane);
g_timeout_add(1000, candy_draw_pane_update, pane);
}
When I replaced my old code, which called gdk_cairo_create() and gdk_drawable_get_clip_region() during my event handlers, with this code, which calls them during candy_draw_pane_init(), the application would no longer draw. Stepping through with a debugger, I can see that pane->window and pane->parent are both NULL pointers while we are within candy_draw_pane_init(). The pointers are valid later, in the Gtk event processing loop. This leads me to believe that the inherited members have not yet been initialized when my derived class' "_init()" method is called. I'm sure this is just the nature of the Gtk+ runtime environment.
So how is this sort of thing typically handled? I could add logic to my event handlers to check priv->cr and priv->region for NULL, and call gdk_cairo_create() and gdk_drawable_get_clip_region() if they are still NULL. Or I could add a "post-init" method to my CandyDrawPane widget and call it explicitly after I call candy_draw_pane_new(). I'm sure lots of other people have encountered this sort of scenario, so is there a clean and conventional way to handle it?
This is my first real foray into object-oriented C, so please excuse me if I'm using any terminology incorrectly. I think one source of my confusion is that Gtk has separate concepts of instance and class initialization. C++ may do something similar "under the hood," but if so, it isn't as obvious to the coder.
I have a feeling that if this was C++, most of the the code that's going into candy_draw_pane_init() would be in the class constructor, and any secondary initialization that depended on the constructor having completed would go into an "Init()" method (which of course is not a feature of the language, but just a commonly used convention). Is there an analogous convention for Gtk+? Or perhaps someone can give a good overview of the flow of control when these widgets are instantiated. I have not been very impressed with the quality of the official Gnome documentation. Much of it is either too high-level, contains errors and typos in code, or has broken links or missing examples. And of course the heavy use of macros makes it a little harder to follow even my own code (in this respect it reminds me of Win32 GUI development). In short, I'm sure I can struggle through this on my own and make it work, but I'd like to hear from someone experienced with Gtk+ and C what the "right" way to do this is.
For completeness, here is the header where I set up my custom widget:
#ifndef __GTKCAIRO_H__
#define __GTKCAIRO_H__ 1
#include <gtk/gtk.h>
/* Following tutorial; see gtkcairo.c */
/* Not sure about naming convention; may need revisiting */
G_BEGIN_DECLS
#define CANDY_DRAW_PANE_TYPE (candy_draw_pane_get_type())
#define CANDY_DRAW_PANE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CANDY_DRAW_PANE_TYPE, CandyDrawPane))
#define CANDY_DRAW_PANE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass)CANDY_DRAW_PANE_TYPE, CandyDrawPaneClass))
#define IS_CANDY_DRAW_PANE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CANDY_DRAW_PANE_TYPE))
#define IS_CANDY_DRAW_PANE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CANDY_DRAW_PANE_TYPE))
// official gtk tutorial, which seems to be of higher quality, does not use this.
// #define CANDY_DRAW_PANE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CANDY_DRAW_PANE_TYPE, CandyDrawPaneClass))
typedef struct {
GtkDrawingArea parent;
/* private */
} CandyDrawPane;
typedef struct {
GtkDrawingAreaClass parent_class;
} CandyDrawPaneClass;
/* method prototypes */
GtkWidget* candy_draw_pane_new(void);
GType candy_draw_pane_get_type(void);
void candy_draw_pane_clear(CandyDrawPane *cdp);
G_END_DECLS
#endif
Any insight is much appreciated. I do realize I could use a code-generating IDE and crank something out more quickly, and probably dodge having to deal with some of this stuff, but the whole point of this exercise is to get a good grasp of the Gtk runtime, so I'd prefer to write the boilerplate by hand.
This article, A Gentle Introduction to GObject Construction, may help you. Here are some tips that I thought of while looking at your code and your questions:
If your priv->cr and priv->region pointers have to change whenever the widget's GDK window changes, then you could also move that code into a signal handler for the notify::window signal. notify is a signal that fires whenever an object's property is changed, and you can narrow down the signal emission to listen to a specific property by appending it to the name of the signal like that.
You don't need to check the return value from the GET_PRIVATE macro. Looking at the source code for g_type_instance_get_private(), it can return NULL in the case of an error, but it's really unlikely, and will print warnings to the terminal. My feeling is that if GET_PRIVATE returns NULL then something has gone really wrong and you won't be able to recover and continue executing the program anyway.
You're not setting up private storage as a global variable. Where are you declaring this global variable? I only see a struct and typedef declaration at the global level. What you are most likely doing, and what is the usual practice, is calling g_type_class_add_private() in the class_init function. This reserves space within each object for your private struct. Then when you need to use it, g_type_instance_get_private() gives you a pointer to this space.
The init method is the equivalent to a constructor in C++. The class_init method has no equivalent, because all the work done there is done behind the scenes in C++. For example, in a class_init function, you might specify which functions override the parent class's virtual functions. In C++, you simply do this by defining a method in the class with the same name as the virtual method you want to override.
As far as I can tell, the only problem with your code is the fact that the GdkWindow of a GtkWidget (widget->window) is only set when the widget has been realized, which normally happens when gtk_widget_show is called. You can tell it to realize earlier by calling gtk_widget_realize, but the documentation recommends connecting to the draw or realize signal instead.

Resources