I'm using Linux Mint 20 to learn GTK. I installed the following package to get started:
sudo apt-get install build-essential libgtk-3-dev
And then proceeded to compile the Hello World app in C:
#include <gtk/gtk.h>
static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *button_box;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_window_close), window);
gtk_container_add (GTK_CONTAINER (button_box), button);
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;
}
As the example requests, I compiled it using:
gcc `pkg-config --cflags gtk+-3.0` -o hello-world-gtk hello-world-gtk.c `pkg-config --libs gtk+-3.0`
But it didn't work, and I have no idea why. It's output was:
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libwayland-client.so.0: referência não definida para "ffi_type_void#LIBFFI_BASE_7.0"
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libwayland-client.so.0: referência não definida para "ffi_call#LIBFFI_BASE_7.0"
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libwayland-client.so.0: referência não definida para "ffi_type_uint32#LIBFFI_BASE_7.0"
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libwayland-client.so.0: referência não definida para "ffi_type_sint32#LIBFFI_BASE_7.0"
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libwayland-client.so.0: referência não definida para "ffi_prep_cif#LIBFFI_BASE_7.0"
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libwayland-client.so.0: referência não definida para "ffi_type_pointer#LIBFFI_BASE_7.0"
collect2: error: ld returned 1 exit status
The "referência não definida para" is Portuguese to something like "undefined reference for".
Anyone knows what I need to do?
I've managed it! The thing is, for some reason my system missed libffi. I downloaded it's latest version, and just installed it:
./configure
(...)
make
(...)
sudo make install
(...)
I've compiled it, and it worked!
Related
I have read the install instructions on GTK for GTK4, which I used
sudo dnf install gtk4 gtk4-devel
The code of the Hello, World example is
#include <gtk/gtk.h>
static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
gtk_window_set_child (GTK_WINDOW (window), button);
gtk_window_present (GTK_WINDOW (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;
}
I used the compile function for GCC:
gcc -o hello-world-gtk hello-world-gtk.c `pkg-config --cflags --libs gtk4`
But this error presents
gtktest.c:1:10: fatal error: gtk/gtk.h: No such file or directory
1 | #include <gtk/gtk.h>
| ^~~~~~~~~~~
As I see, I should have all the requisite packages installed and I am unsure why the compiler cannot pull the gtk library. Any help would be awesome.
Alright I found a strange solution.
For whatever reason, this did not work using their pasted compile code, however when I switched to the below, it worked just fine.
gcc `pkg-config --cflags gtk4` hello.c -o hello `pkg-config --libs gtk4`
I need to compile a simple gtk application for windows using Linux. Here is an example from this link. The compilation via gcc $(pkg-config --cflags gtk+-3.0) -o example-1 example-1.c $(pkg-config --libs gtk+-3.0) works as expected. I installed mingw64 packages for Linux in order to compile for windows.
When I run x86_64-w64-mingw32-gcc $(pkg-config --cflags gtk+-3.0) -o example-1.exe example-1.c $(pkg-config --libs gtk+-3.0) command, I will get this error:
amb#localhost test]$ x86_64-w64-mingw32-gcc $(pkg-config --cflags gtk+-3.0) -o example-1.exe example-1.c $(pkg-config --libs gtk+-3.0)
In file included from /usr/lib64/glib-2.0/include/glibconfig.h:9,
from /usr/include/glib-2.0/glib/gtypes.h:32,
from /usr/include/glib-2.0/glib/galloca.h:32,
from /usr/include/glib-2.0/glib.h:30,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from example-1.c:1:
/usr/include/glib-2.0/glib/gtypes.h: In function '_GLIB_CHECKED_ADD_U64':
/usr/include/glib-2.0/glib/gmacros.h:277:53: error: size of array '_GStaticAssertCompileTimeAssertion_0' is negative
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/glib-2.0/glib/gmacros.h:274:47: note: in definition of macro 'G_PASTE_ARGS'
#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
^~~~~~~~~~~
/usr/include/glib-2.0/glib/gmacros.h:277:44: note: in expansion of macro 'G_PASTE'
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^~~~~~~
/usr/include/glib-2.0/glib/gtypes.h:423:3: note: in expansion of macro 'G_STATIC_ASSERT'
G_STATIC_ASSERT(sizeof (unsigned long long) == sizeof (guint64));
^~~~~~~~~~~~~~~
In file included from /usr/include/glib-2.0/gio/gio.h:46,
from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
from /usr/include/gtk-3.0/gdk/gdk.h:32,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from example-1.c:1:
/usr/include/glib-2.0/gio/gcredentials.h: At top level:
/usr/include/glib-2.0/gio/gcredentials.h:75:1: error: unknown type name 'uid_t'
uid_t g_credentials_get_unix_user (GCredentials *credentials,
^~~~~
/usr/include/glib-2.0/gio/gcredentials.h:79:52: error: unknown type name 'uid_t'; did you mean 'pid_t'?
uid_t uid,
^~~~~
pid_t
I'm new to programming with C and cross compilation. Please explain this problem and provide a solution for me. thx
this is the code (example-1.c):
#include <gtk/gtk.h>
static void
print_hello (GtkWidget *widget,
gpointer data)
{
g_print ("Hello World\n");
}
static void
activate (GtkApplication *app,
gpointer user_data)
{
GtkWidget *window;
GtkWidget *button;
GtkWidget *button_box;
window = gtk_application_window_new (app);
gtk_window_set_title (GTK_WINDOW (window), "Window");
gtk_window_set_default_size (GTK_WINDOW (window), 200, 200);
button_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (window), button_box);
button = gtk_button_new_with_label ("Hello World");
g_signal_connect (button, "clicked", G_CALLBACK (print_hello), NULL);
g_signal_connect_swapped (button, "clicked", G_CALLBACK (gtk_widget_destroy), window);
gtk_container_add (GTK_CONTAINER (button_box), button);
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;
}
I am writing a C program that makes use of fixed pipeline OpenGL and FreeGLUT. However, I would like to use a complete toolkit like GTK+ instead of FreeGLUT. I cannot use GTK3+ as it is not compatible with old OpenGL code, so I would like to use GTK2+.
I found this link with an example program called simple.c:
#include <math.h>
#include <gtk/gtk.h>
#include <GL/gl.h>
#include <gtkgl/gtkglarea.h>
int init (GtkWidget *widget)
{
if (gtk_gl_area_make_current (GTK_GL_AREA(widget)))
{
glViewport(0,0, widget->allocation.width, widget->allocation.height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,100, 100,0, -1,1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
return TRUE;
}
int draw (GtkWidget *widget, GdkEventExpose *event)
{
if (event->count > 0) return TRUE;
if (gtk_gl_area_make_current (GTK_GL_AREA(widget)))
{
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1,1,1);
glBegin(GL_TRIANGLES);
glVertex2f(10,10);
glVertex2f(10,90);
glVertex2f(90,90);
glEnd();
gtk_gl_area_swap_buffers (GTK_GL_AREA(widget));
}
return TRUE;
}
int reshape (GtkWidget *widget, GdkEventConfigure *event)
{
if (gtk_gl_area_make_current (GTK_GL_AREA(widget)))
glViewport(0,0, widget->allocation.width, widget->allocation.height);
return TRUE;
}
int main (int argc, char **argv)
{
GtkWidget *window, *glarea;
int attrlist[] = {
GDK_GL_RGBA,
GDK_GL_RED_SIZE,1,
GDK_GL_GREEN_SIZE,1,
GDK_GL_BLUE_SIZE,1,
GDK_GL_DOUBLEBUFFER,
GDK_GL_NONE };
gtk_init (&argc, &argv);
if (gdk_gl_query () == FALSE) return 0;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "Simple");
gtk_container_set_border_width (GTK_CONTAINER(window), 10);
g_signal_connect (window, "delete_event",
G_CALLBACK (gtk_main_quit), NULL);
/* You should always delete gtk_gl_area widgets before exit or else
GLX contexts are left undeleted, this may cause problems (=core dump)
in some systems.
Destroy method of objects is not automatically called on exit.
You need to manually enable this feature. Do gtk_quit_add_destroy()
for all your top level windows unless you are certain that they get
destroy signal by other means. */
gtk_quit_add_destroy (1, GTK_OBJECT(window));
glarea = GTK_WIDGET(gtk_gl_area_new (attrlist));
gtk_widget_set_size_request (GTK_WIDGET(glarea), 100, 100);
gtk_widget_set_events (GTK_WIDGET(glarea), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
g_signal_connect (glarea, "expose_event", G_CALLBACK(draw), NULL);
g_signal_connect (glarea, "configure_event", G_CALLBACK(reshape), NULL);
g_signal_connect (glarea, "realize", G_CALLBACK(init), NULL);
gtk_container_add (GTK_CONTAINER(window), GTK_WIDGET(glarea));
gtk_widget_show (GTK_WIDGET(glarea));
gtk_widget_show (GTK_WIDGET(window));
gtk_main ();
return 0;
}
but unfortunately it requeries a file that I don't know where to get, gtk_opengl.h
I unsuccessfully tried to compile this simple.c code with
gcc simple.c -o helloworld `pkg-config --libs gtk+-2.0`
and, of course, got the following error:
fatal error: gtk_opengl.h: No such file or directory
Any ideas on how to make simple.c compile? Or on how to combine OpenGL with GTK2+?
On my Debian Stable box I had to install libgtkgl2.0-dev and add --cflags & gtkgl-2.0 to the pkg-config invocation:
gcc simple.c -o helloworld `pkg-config --cflags --libs gtk+-2.0 gtkgl-2.0`
I'm running a basic GTK app from the GTK website's tutorials, and I'm getting the following warning:-
*** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.
I've installed the gtk+ and gtk+3 packages with brew. Here is the code from the file:-
#include
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);
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;
}
I'm running OS X 10.10.5, MacBook Pro 13in Retina.
Any ideas? Thanks!
I have pretty simple application with text entry and button.
When user press on button , the application downloads file (in other thread) from URL and on success opens dialog message that all done. During downloading i activate spinner (like busy)
Since I don't know how long will take connect to download file I use separate thread for that purpose. But on "dialog show" my application fails and I get followed error:
(enter_license.exe:210232): Gdk-WARNING **: gdkdrawable-win32.c:1873: GetDC failed: Invalid window handle.
(enter_license.exe:210232): Gdk-WARNING **: gdkgc-win32.c:968: GetCurrentObject failed: The handle is invalid.
(enter_license.exe:210232): Gdk-WARNING **: gdkgc-win32.c:970: RestoreDC failed: The handle is invalid.
(enter_license.exe:210232): Gdk-CRITICAL **: _gdk_win32_drawable_release_dc: assertion `impl->hdc_count > 0' failed
(enter_license.exe:210232): Gdk-WARNING **: gdkwindow-win32.c:2216: SetWindowLongPtr failed: Invalid window handle.
Sounds like something wrong when I try to call GTK object from separate thread.
Maybe somehow I need call handle (callback) to implement "show_dialog" in main thread?
Compile:
gcc -IC:/MinGW/include -o enter_license enter_license.c `pkg-config --libs --cflags gtk+-2.0 gthread-2.0``
Flow: main -> call "do_something" -> create thread and call "argument_thread" ->
Here is a snippets of code:
typedef struct _Data
{
GtkWidget *win;
} Data;
main
int main(int argc, char **argv)
{
GtkWidget *window;
gtk_init(&argc, &argv);
window = do_something(NULL, argv);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
do_something
GtkWidget * do_something(GtkWidget *do_widget, char **argv){
....
GtkWidget *window;
if (!window){
window = gtk_dialog_new_with_buttons ("GtkSpinner",
GTK_WINDOW (do_widget),
0,
GTK_STOCK_CLOSE,
GTK_RESPONSE_NONE,
NULL);
gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
g_signal_connect (window, "response", G_CALLBACK (gtk_widget_destroy), NULL);
g_signal_connect (window, "destroy", G_CALLBACK (gtk_widget_destroyed), &window);
....
if (!gtk_widget_get_visible (window)){
gtk_widget_show_all (window);
}
else{
gtk_widget_destroy (window);
}
// define thread
GThread* thread;
GError* err;
Data data;
data.win = window;
thread = g_thread_create((GThreadFunc)argument_thread,&data,FALSE, &err);
return window;
}
show_dialog
gboolean show_dialog( GtkWidget* mw)
{
GtkWidget *dialog;
printf("BOO: \n");
// here all works fine
sleep(3000);
gtk_widget_show(spinner_sensitive);
gtk_spinner_start (GTK_SPINNER (spinner_sensitive));
sleep(3000);
gtk_spinner_stop (GTK_SPINNER (spinner_sensitive));
sleep(3000);
gtk_widget_hide(spinner_sensitive);
printf("BOO\n");
// here dialog is shown for 1-10 milisec and get error.
dialog = gtk_message_dialog_new (GTK_WINDOW(mw),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
"Downloaded successfully");
g_signal_connect_swapped (G_OBJECT (dialog), "response",
G_CALLBACK (gtk_widget_destroy),
G_OBJECT (dialog));
gtk_widget_show(dialog);
printf("BOO\n");
}
argument_thread
void *argument_thread( gpointer ptr ) {
Data *data = (Data*)ptr;
gdk_threads_enter();
show_dialog (data->win);
gdk_threads_leave();
return( NULL );
}
Please help me,
Any and all suggestions would be greatly appreciated
GTK is not thread-safe so anything that interacts with the GUI will have to run on the main thread.
Use the g_idle_add function to notify your main thread when the download has finished.
According to #VincentPovirk just for guys who looking for answer, here is a working implementation:
into the Thread we call g_idle_add and call callback_func that will be implemented outside of second Thread (aka in main):
gboolean show_dialog( GtkWidget* mw)
{
sleep(3000);
gtk_widget_show(spinner_sensitive);
gtk_spinner_start (GTK_SPINNER (spinner_sensitive));
sleep(3000);
gtk_spinner_stop (GTK_SPINNER (spinner_sensitive));
gtk_widget_hide(spinner_sensitive);
g_idle_add(callback_func, NULL);
}
gint callback_func(void *unused)
{
GtkWidget *dialog;
dialog = gtk_message_dialog_new (GTK_WINDOW(window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_INFO,
GTK_BUTTONS_CLOSE,
"Succeeded.");
g_signal_connect_swapped (G_OBJECT (dialog), "response",
G_CALLBACK (gtk_widget_destroy),
G_OBJECT (dialog));
gtk_widget_show(dialog);
return FALSE;
}