LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 05-15-2015, 03:48 PM   #1
mdooligan
Member
 
Registered: Feb 2009
Location: Vancouver BC
Distribution: Mandrake10/ArchHackery/Gentoo
Posts: 179

Rep: Reputation: 22
GTK, typedef, and macro jiggery-pokery...


Just to frame things up, I'm doing a clean-up pass on some big interface code in GTK and I've run into a curious issue. Let me explain:

I use glade-2 to bodge the basic code chunks together, and then mogrify them into what I need. In this case it's a column of 8 buttons. Of course glade-2 does a lovely job and makes 8 big blobs of button creation code that take up 4 or 5 screenfuls. That's a good thing. I'm looking at this and know I can make it cleaner and more sophisticated. What I do is this:
Code:
typedef GtkWidget *(*PCFunc)(gpointer);
typedef gboolean (*BTN_cb)(GtkWidget*, GdkEventButton*, gpointer );
No problem. Then this:
Code:
/*--------------------------------------------------------------------------*/
typedef struct _btn_cfg btn_cfg;
struct _btn_cfg
{
    char *name;
    PCFunc create_func;
    BTN_cb cb_func;
};
btn_cfg t1btns[] = {
    {"<b>LOC_K\nSCREEN</b>", create_lock_btn, (BTN_cb)lock_btn_cb},
    {"<b>L_OG\nOUT</b>", NULL},
    {"Start\nShift", NULL},
    {"End\nShift", NULL},
    {"Cash\nIn", NULL},
    {"Cash\nOut", NULL},
    {"Msg", NULL},
    {"_Admin", NULL},
    {NULL}
};
/*--------------------------------------------------------------------------*/
There's the 8 buttons defined all nice and everything. I've left them all out but the first, for clarity. Here's the create_func and cb_func for the first one:
Code:
/*--------------------------------------------------------------------------*/
BTN_cb lock_btn_cb (GtkWidget*w, GdkEventButton*e, gpointer d){
    printf ("%s\n", __FUNCTION__);
    static int state = 0;
    state = !state;
    if (!K.logonwin) {
        K.logonwin = create_logonwin ();
    }
    if(state) {
        gtk_widget_hide (K.mainwin);
        gtk_widget_show (K.logonwin);
        K.logonOKbtn = w;
        system (SCREEN_BLANK_COMMAND);
    } else {
        gtk_widget_hide (K.logonwin);
        gtk_widget_show (K.mainwin);
    }
    return (void*)TRUE;
}
/*--------------------------------------------------------------------------*/
GtkWidget *create_lock_btn (void *data)
{
    GtkWidget *w = NULL;
    char *name = (char*)data;
    w = gtk_button_new_with_mnemonic (name);
    button_center_label (w);
    return w;
}
/*--------------------------------------------------------------------------*/
It works great. No problem.

2 questions:

#1: Why do I need to cast (BTN_cb)lock_btn_cb in the struct definition like this or I get:
Code:
t1.c:97: warning: initialization from incompatible pointer type
#2. Why do I need to cast TRUE to (void*) in the BTN_cb or I get:
Code:
t1.c: In function `lock_btn_cb':
t1.c:77: warning: return makes pointer from integer without a cast
Somehow I think this has to do with macro jiggery pokery. That's a term I got from a guy on another forum when we were talking about the open() func.

Really, this is not a big issue. Just a puzzlement that I'd like to figure out for my own knowledge. I like getting clean compiles with -Wall, it often leads me into odd things, like this.
 
Old 05-15-2015, 04:34 PM   #2
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
#1 & #2
Here:
Code:
typedef gboolean (*BTN_cb)(GtkWidget*, GdkEventButton*, gpointer );
You've defined a function pointer called BTN_cb and here:
Code:
BTN_cb lock_btn_cb (GtkWidget*w, GdkEventButton*e, gpointer d)
You begin the definition of a function that returns a callback.

Therefore the compiler considers the callback function itself incorrect and you are telling it to ignore the error with your cast. In addition the value of TRUE (gboolean) is not what is declared as a return value so you are telling the compiler, ignore my error by casting it to a void*. What you problably mean to say is:
Code:
gboolean lock_btn_cb (GtkWidget*w, GdkEventButton*e, gpointer d){
Then the lock_btn_cb has the correct signature and won't require a cast and your return value will also be correct and not in need of a cast.
 
1 members found this post helpful.
Old 05-16-2015, 01:07 PM   #3
mdooligan
Member
 
Registered: Feb 2009
Location: Vancouver BC
Distribution: Mandrake10/ArchHackery/Gentoo
Posts: 179

Original Poster
Rep: Reputation: 22
Perfect. Thank you very much. Now that it's fixed, I'm trying to figure out what I was thinking at the time. Seems obvious now.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
C typedef notation. corp1126 Programming 6 11-24-2009 10:40 AM
typedef in C Oaks Programming 1 08-05-2009 09:49 AM
[C] The FAR in typedef koyi Programming 2 07-21-2006 07:37 PM
#defining a macro inside a macro? saravkrish Programming 1 05-24-2005 09:48 PM
Can you help me with typedef? brownstone Programming 3 06-11-2004 10:09 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 06:39 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration