EDIT
This question ended up being two problems packed into one. Yet, I cannot delete the question. The scope of the original question regarding pointers was solved by #David Ranieri. The mmap/fork/gtk problem will be the scope of a new question and will not be addressed here.
I want to print a value I have stored in memory in a GTK window. The integer must be stored using mmap to be retained during a fork elsewhere in the code. I cannot reference this memory mapped address from GTK without getting a SegFault. Am I doing something wrong here? Is there a better way?
My current strategy:
Reserve memory for an int with mmap at *VAL
Fork process, one half modifies VAL the other half runs GTK
Pass *VAL to app in userdata slot
The userdata now called localval in activate()
Print the value at address localval by converting from gpointer to int.
MWE (this causes a segfault, run at your own risk):
/*
* MMAP Variable SegFault
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static void activate (GtkApplication *app, gpointer *localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *exit_button;
// Text
GtkWidget *text_status;
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
exit_button = gtk_button_new_with_label ("Exit");
gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
// Define text status
char msg[32]={0};
// The "print" line
g_snprintf(msg, sizeof msg, "val: %d\n", GPOINTER_TO_INT(*localval));
text_status = gtk_label_new(msg);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
//Activate!
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
In a non-working alternative to this code, I tried changing the print line to:
g_snprintf(msg, sizeof msg, "val: %d\n", &GPOINTER_TO_INT(*localval));
But the compiler thinks I want to use the & as a comparator.
You are passing a dereferenced pointer (a value) to a function expecting a pointer:
int *VAL = ...;
...
g_signal_connect (app, "activate", G_CALLBACK (activate), (gpointer *)*VAL);
switch to
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL); // Do not use a wrong cast (void **)
also, gpointer is an alias of void *, using gpointer *data you get a void **data, not what you want, so
static void activate (GtkApplication *app, gpointer *localval) {
should be
static void activate (GtkApplication *app, gpointer localval) { // without *
finally, to print the value of the pointer use
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
Related
Context and Question
For reasons, I need to fork my code and update a variable on both forks. The variable is stored in memory via mmap so it is accessible to all processes. On one child process, I increment the variable. How do I tell the GTK application to refresh/update/redraw from the child process?
MWE
/*
* Update GTK label from variable stored in mmap
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static void activate (GtkApplication *app, gpointer localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *exit_button;
// Text
GtkWidget *text_status;
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
exit_button = gtk_button_new_with_label ("Exit");
gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
// Define text status
char msg[32]={0};
// The "print" line
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
text_status = gtk_label_new(msg);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
//Activate!
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
gtk_label_set_text(GTK_LABEL(text_status), msg);
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
// Increments here should be reflected outside this PID.
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
What happens at runtime
When the MWE is run, the terminal dutifully prints the value each time it updates. However, the GTK window forever says "val: 1". We can tell the value stored in mmap is accessible to the GTK process by adding usleep(3000000) in the activate process just before gtk_widget_show_all. In this variant, the window will forever show "val: 4".
The Question Reiterated
How do I make the output on the GTK window match the terminal?
That's because activate is called only once (when the window is loaded/activated) but nothing is refreshing the label once loaded, I did some changes in the code (using a global, very ugly but simple to ilustrate the problem), the "Exit Button" is now a "Refresh Button". Press it and you will see the changes in VAL.
/*
* Update GTK label from variable stored in mmap
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static GtkWidget *text_status;
static void refresh(GtkWidget *widget, gpointer data)
{
(void)widget;
char msg[32]={0};
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)data);
gtk_label_set_text(GTK_LABEL(text_status), msg);
}
static void activate (GtkApplication *app, gpointer localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *refresh_button;
// Text
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
refresh_button = gtk_button_new_with_label ("Refresh");
gtk_container_add(GTK_CONTAINER (button_box_quit), refresh_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect(refresh_button, "clicked", G_CALLBACK (refresh), localval);
// Define text status
char msg[32]={0};
// The "print" line
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
text_status = gtk_label_new(msg);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
//Activate!
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)localval);
gtk_label_set_text(GTK_LABEL(text_status), msg);
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
// Increments here should be reflected outside this PID.
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
If you want to refresh the label without pressing a button, you can use g_timeout_add and set a function to be called at regular intervals refreshing VAL.
g_timeout_add solution
To allow for an automatic update of the main loop from the application we can use g_timeout_add as #David Ranieri pointed out. However, the API of GTK3 requires we pass the refresh function slightly differently to g_timeout_add.
Modifying the OP MWE and #David Ranieri's answer:
/*
* Update GTK label from variable stored in mmap
* Timeout Method
*/
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <gtk/gtk.h>
static GtkWidget *text_status;
static gboolean refresh(gpointer data) {
char msg[32]={0};
g_snprintf(msg, sizeof msg, "val: %d\n", *(int *)data);
gtk_label_set_text(GTK_LABEL(text_status), msg);
return TRUE;
}
static void activate (GtkApplication *app, gpointer localval) {
GtkWidget *window;
// Button Containers
GtkWidget *button_box_quit;
// Buttons
GtkWidget *exit_button;
// Define Window, dynamic size for screen.
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "test");
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
// Define Button Boxes.
button_box_quit = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
// Define Exit Button, put it in a box, put box in window
exit_button = gtk_button_new_with_label ("Exit");
gtk_container_add(GTK_CONTAINER (button_box_quit), exit_button);
gtk_container_add(GTK_CONTAINER (window), button_box_quit);
// Connect signals to buttons
g_signal_connect_swapped (exit_button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
// Define text status
text_status = gtk_label_new(NULL);
gtk_container_add(GTK_CONTAINER (button_box_quit), text_status);
// Define timeout
g_timeout_add(500, G_SOURCE_FUNC(refresh), localval);
// Activate!
refresh(localval);
gtk_widget_show_all (window);
}
int main (int argc, char **argv) {
GtkApplication *app;
int status;
int *VAL = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int *ABORT = mmap(NULL, sizeof(int), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
int pid = fork();
if (pid == 0) {
while(!*ABORT) {
printf("%d\n", *VAL);
// Increments here should be reflected outside this PID.
*VAL = *VAL + 1;
usleep(1000000);
}
exit(0);
} else {
app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
// The passing line
g_signal_connect (app, "activate", G_CALLBACK (activate), VAL);
status = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
*ABORT = 1;
}
*ABORT = 1;
return status;
}
The important differences:
We no longer pass the empty widget to refresh like we do when using a callback.
GTK3 must be explicitly told that refresh is a G_SOURCE_FUNC.
This code make a program that create a window with label, if you click the label, the program executes an fprintf of buffer passed as an argument of g_signal_connect(G_OBJECT(eventbox), "button_press_event", G_CALLBACK(on_event_clicked), buffer). Previously the program put in buffer the string "Hello Word" and then the program should print this message, but maybe the program print only garbled char. Where I'm wrong?
#include <gtk/gtk.h>
#include <stdlib.h>
#include <string.h>
void on_event_clicked (GtkWidget* widget, gpointer user_data);
int main (int argc, char **argv) {
GtkWidget *window;
GtkWidget *eventbox;
GtkWidget *label;
char* buffer = malloc(sizeof(char)*10);
strcpy(buffer, "Hello Word\0");
gtk_init (&argc,&argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
label = gtk_label_new ("Hello Word");
eventbox = gtk_event_box_new ();
gtk_container_add (GTK_CONTAINER(eventbox), label);
gtk_container_add (GTK_CONTAINER(window), eventbox);
gtk_widget_show_all (window);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(eventbox), "button_press_event",
G_CALLBACK(on_event_clicked), buffer);
gtk_main();
return 0;
}
void on_event_clicked (GtkWidget *widget, gpointer user_data) {
char* pn = user_data;
fprintf(stderr, "%s\n", pn);
}
Your prototype for on_event_clicked() is wrong, it doesn't match what GTK+ expects.
It should be:
gboolean user_function (GtkWidget *widget, GdkEvent *event, gpointer user_data);
You need to add the missing argument to your function, and also deal with the requirement for a return value. Remember to read the signal documentation seriously.
I am trying to change the cursor of a window dynamically with GTK3 but gtk_widget_get_parent_window doesn't seem to work.
Could someone please point out what I'm doing wrong? Thanks!
// https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
// minimal example
#include <gtk/gtk.h>
static void
activate (GtkApplication* app,
gpointer user_data)
{
GtkWidget *window;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
// Here \/\/\/\/\/ .
GdkWindow* w = gtk_widget_get_parent_window(window);
GdkCursor* c = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_WATCH);
gdk_window_set_cursor(w, c);
// /\/\/\/\/\ .
gtk_widget_show_all (window);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int status;
app = gtk_application_new ("org.gtk.example", 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;
}
(main.exe:16508): Gdk-CRITICAL **: gdk_window_set_cursor: assertion
'GDK_IS_WINDOW (window)' failed
I am using GTK 3.16 with msys2
Many thanks in advance.
Extending #andlabs comment
Any attempt to change the cursor needs to be done after the widget has been added to the widget hierarchy or in GTK terms realized.
Calling gtk_widget_get_parent_window() or even gtk_widget_get_window() before a realize event has been fired for the widget will result in a NULL pointers in both cases.
Like #andlabs it is safer to use gtk_widget_get_window() in combination with a GtkWindow.
The solution.
static GdkWindow* G_WINDOW = 0;
static GdkCursor* G_CURSOR = 0;
// call after WindowRealize()
void changecursor()
{
assert(G_WINDOW != NULL);
gdk_window_set_cursor(G_WINDOW, G_CURSOR);
}
static void WindowRealize(GtkWidget *window, gpointer data)
{
G_CURSOR_HAND = gdk_cursor_new_for_display(gdk_display_get_default(), GDK_HAND2);
G_WINDOW = gtk_widget_get_window(window);
}
static void activate(GtkApplication* app,gpointer user_data)
{
GtkWidget *window = gtk_application_window_new(app);
...
g_signal_connect(window, "realize", G_CALLBACK(WindowRealize), NULL);
gtk_widget_show_all (window);
}
Currently I am writing a program in C, on a linux system (Raspberry Pi to be exact) which should draw to a GTK window using Cairo. I've been following the tutorial at: http://zetcode.com/gfx/cairo/ . But it is way to vague with it's explanations at certain points.
It does not explain two points that I really need:
I can't figure out a way to draw to the window with a proper function call.
It removes what is already drawn.
I need a piece of code that does some simple things, in a very Object-Oriented manner:
Draw lines to a GTK window with a function call, given X and Y for both starting and end point;
Do not remove what is previously drawn;
All initializations of variables and the window should be outside the main function.
So basically something similar to this:
#include <cairo.h>
#include <gtk/gtk.h>
void drawLine(int xStart, int yStart, int yEnd, int xEnd) {
//Drawing code here.
}
void initializeCairo() {
//Insert cairo initialization.
}
void initializeGTK() {
//Insert GTK initialization.
}
/*If needed a general initializer for both cairo and GTK*/
void initialize() {
//Insert general initialization.
}
int main (int argc, char *archv[]) {
intializeGTK();
initializeCairo();
if(doSomething) {
drawLine(10, 10, 20, 20);
}
}
If it could be explained what a method does (in proper English please, not a reference to the documentation), that'd be absolutely great.
Also please include the gcc build command used.
Thanks in advance!
The answers from andlabs are fine. Here is in addition a short (although not entirely elegant) example. It will "kind of remember" the last NUM lines - creation/resize/activation/deactivation of the window will trigger a "draw" of the content. A Next button click will add a new line to the output. Check also the command-line output for an update of
the array values that are drawn.
#include <gtk/gtk.h>
#include <glib/gprintf.h>
#include <cairo.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#define NUM 3
typedef struct {
GtkApplication *app;
GtkWidget *window;
GtkWidget *button;
GtkWidget *da;
cairo_t* cr;
gboolean redraw;
gint xsize;
gint ysize;
} appWidgets;
gboolean drawEvent (GSimpleAction *action, GVariant *parameter, gpointer data);
void nextCallback (GtkWidget *widget, gpointer data);
void nextCallback (GtkWidget *widget, gpointer data)
{
appWidgets *w = (appWidgets*) data;
static gint cnt = 0;
static gdouble x[NUM], y[NUM], u[NUM], v[NUM];
// determine the next coordinates for a line
if (w->redraw == FALSE) {
x[cnt] = g_random_double();
y[cnt] = g_random_double();
u[cnt] = g_random_double();
v[cnt] = g_random_double();
}
w->cr = gdk_cairo_create (gtk_widget_get_window (w->da));
// map (0,0)...(xsize,ysize) to (0,0)...(1,1)
cairo_translate (w->cr, 0, 0);
cairo_scale (w->cr, w->xsize, w->ysize);
// set linewidth
cairo_set_line_width (w->cr, 0.005);
// draw the lines
for (int k = 0; k < NUM; k++) {
cairo_move_to (w->cr, x[k], y[k]);
cairo_line_to (w->cr, u[k], v[k]);
cairo_stroke (w->cr);
g_print("k=%d:(%1.2lf,%1.2lf).(%1.2lf,%1.2lf) ",
k, x[k], y[k], u[k], v[k]);
}
g_print("\n");
cairo_destroy (w->cr);
if (w->redraw == FALSE) {
cnt++;
if (cnt == NUM)
cnt = 0;
}
}
gboolean drawEvent (GSimpleAction *action, GVariant *parameter, gpointer data)
{
appWidgets *w = (appWidgets*) data;
w->xsize = gtk_widget_get_allocated_width (w->da);
w->ysize = gtk_widget_get_allocated_height (w->da);
w->redraw = TRUE;
nextCallback (NULL, w);
w->redraw = FALSE;
return TRUE;
}
void activate (GtkApplication *app, gpointer data)
{
GtkWidget *box;
appWidgets *w = (appWidgets*) data;
w->window = gtk_application_window_new (w->app);
gtk_window_set_application (GTK_WINDOW (w->window), GTK_APPLICATION (w->app));
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_container_add (GTK_CONTAINER (w->window), box);
w->da = gtk_drawing_area_new();
gtk_widget_set_size_request (w->da, 400, 400);
gtk_box_pack_start (GTK_BOX (box), w->da, TRUE, TRUE, 0);
g_signal_connect (w->da, "draw", G_CALLBACK (drawEvent), (gpointer) w);
w->button = gtk_button_new_with_label ("Next");
g_signal_connect (G_OBJECT (w->button), "clicked", G_CALLBACK (nextCallback),
(gpointer) w);
gtk_box_pack_start (GTK_BOX (box), w->button, FALSE, TRUE, 0);
gtk_widget_show_all (GTK_WIDGET (w->window));
w->redraw = FALSE;
}
int main (int argc, char *argv[])
{
gint status;
appWidgets *w = g_malloc (sizeof (appWidgets));
w->app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
g_signal_connect (w->app, "activate", G_CALLBACK (activate), (gpointer) w);
status = g_application_run (G_APPLICATION (w->app), argc, argv);
g_object_unref (w->app);
g_free (w);
w = NULL;
return status;
}
Build the program as usual:
gcc example.c -o example `pkg-config --cflags --libs gtk+-3.0`
I have the following example from here, it shows this under the "Increase - Decrease" title.
#include <gtk/gtk.h>
gint count = 0;
char buf[5];
void increase(GtkWidget *widget, gpointer label)
{
count++;
sprintf(buf, "%d", count);
gtk_label_set_text(label, buf);
}
void decrease(GtkWidget *widget, gpointer label)
{
count--;
sprintf(buf, "%d", count);
gtk_label_set_text(label, buf);
}
int main(int argc, char** argv) {
GtkWidget *label;
GtkWidget *window;
GtkWidget *frame;
GtkWidget *plus;
GtkWidget *minus;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 250, 180);
gtk_window_set_title(GTK_WINDOW(window), "+-");
frame = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), frame);
plus = gtk_button_new_with_label("+");
gtk_widget_set_size_request(plus, 80, 35);
gtk_fixed_put(GTK_FIXED(frame), plus, 50, 20);
minus = gtk_button_new_with_label("-");
gtk_widget_set_size_request(minus, 80, 35);
gtk_fixed_put(GTK_FIXED(frame), minus, 50, 80);
label = gtk_label_new("0");
gtk_fixed_put(GTK_FIXED(frame), label, 190, 58);
gtk_widget_show_all(window);
g_signal_connect(window, "destroy",
G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect(plus, "clicked",
G_CALLBACK(increase), label);
g_signal_connect(minus, "clicked",
G_CALLBACK(decrease), label);
gtk_main();
return 0;
}
what I'm wondering is, the g_signal_connect(plus, "clicked",G_CALLBACK(increase), label); function sends the "label" to the function increase, where its arguments are void increase(GtkWidget *widget, gpointer label). Now in the increase function the gtk_label_set_text() function requires a data type of GtkLabel as its first argument but I only see a GtkWidget variable and a void pointer label as the arguments to the increase function. If that is so how does the gtk_label_set_text() work?.
In C (but not C++), you can implicitly cast a void* to a pointer to any other type. It's very commonly seen when allocating memory with malloc, which returns a void*:
int *myIntArray = malloc(10 * sizeof(int)); // allocate array of 10 ints
Your code is doing the same thing, just with parameter passing:
void gtk_label_set_text(GtkLabel *label, const char *text);
void *label = ...;
gtk_label_set_text(label, "some string"); // label is implicitly cast from
// void* to GtkLabel*