GTK+: leaks memory with gtk_label_set_text - windows

I have installed last all-in-one bundle GTK+ for windows 32 bit.
I have a problem with function gtk_label_set_text: it leaks memory when it is called recursively
There is an example code below. It leaks memory about 1Mb every 20 seconds
#include <gtk/gtk.h>
gboolean update_label(gpointer);
int main(int argc, char ** argv)
{
GtkWidget *window;
GtkWidget *label = NULL;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
label = gtk_label_new(NULL);
gtk_container_add(GTK_CONTAINER(window),label);
gtk_widget_show_all(window);
g_timeout_add(10,(GtkFunction)update_label,label);
gtk_main();
return 0;
}
gboolean update_label(gpointer data)
{
GtkWidget *label = data;
gchar tmpbuf[100];
sprintf(tmpbuf , "Random text %i\n",rand());
gtk_label_set_text(GTK_LABEL(label),tmpbuf);
return TRUE;
}
The code creates a windows with label and updates it every 10 ms.
Can someone help me? Is there something wrong in GTK+ library or in my code?
Thanks

This is most probably a duplicate Memory leak in GTK under Windows 7 in gtk_widget_queue_draw. What is the version of GTK you use ?

Related

Failed to load keyboard layout DLL for layout A0000409: C:\WINDOWS\system32\kbdPrlUS.dll

My ultimate goal is to compile and build a GTK application for Windows using only the C programming language
I'm using a Macbook Pro with the M1 chip. So instead of developing on Mac and cross compiling for windows, I decided to try and develop on Windows for windows.
I'm using parallels to run a Windows 10 virtual machine and after a lot of trial and error I was finally able to compile and execute a GTK program using msys2.
There is just one problem: No keyboard functionality in the GTK application. With the error message in the command prompt: "Failed to load keyboard layout DLL for layout A0000409: C:\WINDOWS\system32\KbdPrlUS.dll"
I solved my previous DLL issue by adding a path to the system variables. How might I approach addressing this keyboard layout DLL issue? The file definitely already exists at that location.
EDIT Here is the code that compiles (and works) but doesn't register and letter keypress from the keyboard. The same code works on Mac OS just fine.
#include <gtk/gtk.h>
static GtkTextBuffer *tb = NULL;
static GtkTextBuffer *tb2 = NULL;
static void
quit_activated(GSimpleAction *action,
GVariant *parameter,
gpointer user_data)
{
GApplication *app = G_APPLICATION (user_data);
g_application_quit (app);
}
static void
click1_cb (GtkButton *btn,
gpointer user_data)
{
GtkTextIter start, end;
gtk_text_buffer_get_bounds(tb, &start, &end);
const GtkTextIter* start2 = &start;
const GtkTextIter* end2 = &end;
char* text = gtk_text_buffer_get_text(tb,start2,end2,false);
gtk_text_buffer_set_text (tb2, text, -1);
}
static void
app_activate (GApplication *app,
gpointer user_data)
{
GtkWidget *win;
GtkWidget *tv;
GtkWidget *tv2;
GtkWidget *box;
GtkWidget *btn;
GtkWidget *btn2;
gchar *text;
text =
"Input some text "
"As many lines as you want\n"
"One day, he went into a mountain and found a shining bamboo. "
"\"What a mysterious bamboo it is!,\" he said. "
"He cut it, then there was a small cute baby girl in it. "
"The girl was shining faintly. "
"He thought this baby girl is a gift from Heaven and took her home.\n"
"His wife was surprized at his tale. "
"They were very happy because they had no children. "
;
win = gtk_application_window_new (GTK_APPLICATION (app));
gtk_window_set_title (GTK_WINDOW (win), "Taketori");
gtk_window_set_default_size (GTK_WINDOW (win), 400, 300);
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
gtk_window_set_child (GTK_WINDOW (win), box);
btn = gtk_button_new_with_label ("Execute.");
g_signal_connect (btn, "clicked", G_CALLBACK (click1_cb), NULL);
tv = gtk_text_view_new ();
tv2 = gtk_text_view_new ();
tb = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv));
tb2 = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv2));
gtk_text_buffer_set_text (tb2, "", -1);
gtk_text_buffer_set_text (tb, text, -1);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), GTK_WRAP_WORD_CHAR);
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv2), GTK_WRAP_WORD_CHAR);
gtk_box_append (GTK_BOX (box),tv);
gtk_box_append (GTK_BOX (box), tv2);
gtk_box_append (GTK_BOX (box), btn);
/*
GSimpleAction *act_quit = g_simple_action_new ("quit", NULL);
g_action_map_add_action (G_ACTION_MAP (app), G_ACTION(act_quit));
g_signal_connect (act_quit,"activate",G_CALLBACK (quit_activated),app);
GMenu *menubar = g_menu_new();
GMenuItem *menu_item_menu = g_menu_item_new ("Menu",NULL);
GMenu *menu = g_menu_new();
GMenuItem *menu_item_quit = g_menu_item_new ("Quit","app.quit");
g_menu_append_item (menu, menu_item_quit);
g_object_unref (menu_item_quit);
g_menu_set_submenu (menu_item_menu,G_MENU_MODEL(menu));
g_menu_append_item (menubar,menu_item_menu);
g_object_unref(menu_item_menu);*/
//gtk_application_set_menubar (GTK_APPLICATION (app), G_MENU_MODEL (menubar));
//gtk_application_window_set_show_menubar (GTK_APPLICATION_WINDOW (win), TRUE);
gtk_widget_show (win);
}
int
main (int argc,
char **argv)
{
GtkApplication *app;
int stat;
app = gtk_application_new ("com.gitbut.fff", G_APPLICATION_FLAGS_NONE);
g_signal_connect (app, "activate", G_CALLBACK (app_activate), NULL);
stat = g_application_run (G_APPLICATION (app), argc, argv);
g_object_unref (app);
return stat;
}

gtk glade need help

I am using glade to make an user interface.
i have successfully generated the glade file
Now i have to include this file in my C code.
I am using following code:
#include <stdlib.h>
#include<gtk/gtk.h>
int main (int argc, char *argv[])
{
GtkWidget *builder,*window,*button;
gtk_init (&argc, &argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"shiv.glade",NULL);
window=GTK_WIDGET (gtk_builder_get_object(builder,"window1")) ;
button=GTK_WIDGET (gtk_builder_get_object(builder,"button1"));
g_object_unref(G_OBJECT(builder));
gtk_widget_show(button);
gtk_widget_show(window);
gtk_main ();
return 0;
}
My UI is a simple window having a button without any callback function.
I am getting following errors on execution
GTK-CRITICAL **: IA__gtk_widget_show assertion 'GTK_IS_WIDGET(widget)' failed
Change:
GtkWidget *builder,*window,*button;
with:
GtkWidget *window,*button;
GtkBuilder *builder;
this should fix.
Example:
#include <stdlib.h>
#include <gtk/gtk.h>
static void
close_window ( GtkWidget *widget, gpointer window)
{
printf("application close...\n");
gtk_widget_destroy((GtkWidget*)window);
}
int main (int argc, char *argv[])
{
GtkWidget *window, *button;
GtkBuilder *builder;
gtk_init (&argc, &argv);
builder=gtk_builder_new();
gtk_builder_add_from_file(builder,"a.glade",NULL);
window = GTK_WIDGET (gtk_builder_get_object(builder,"window1")) ;
button = GTK_WIDGET (gtk_builder_get_object(builder,"button1"));
g_signal_connect (G_OBJECT (button), "clicked",G_CALLBACK (close_window),window);
g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window));
g_object_unref(G_OBJECT(builder));
gtk_widget_show_all( window );
gtk_main ();
return 0;
}
From GTK3 reference manual:
GtkBuilder — Build an interface from an XML UI definition;
GtkWidget — Base class for all widgets

Ogre and Allegro direct3d device 9 conflict

I've been trying to write a program that uses Allegro 5 to handle 2D rendering and and Ogre for 3D rendering but I've had problems with initialization, I've got most of the issues down which were the hInstance of the window, but now the issue is that Ogre::D3D9RenderWindow::setDevice() only takes Ogre's type and that is set by an ID3Device9 according to the Ogre API reference and not what al_get_d3d9_device() returns which is an LPDIRECT3DDEVICE9. I need help trying to figure out how to convert the LPDIRECT3DDEVICE9 to a ID3Device9.
Here is the code the I have so far:
#include "stdafx.h"
int _tmain(int argc, _TCHAR* argv[])
{
ALLEGRO_DISPLAY *al_display = NULL;
if(!al_init())
{
fprintf(stderr, "Cannot initialize allegro");
return -1;
}
al_display = al_create_display(640, 480);
if(!al_display)
{
fprintf(stderr,"Cannot initialize the display");
return -1;
}
HWND hWnd = al_get_win_window_handle(al_display);
HINSTANCE hInst = (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE);
Ogre::D3D9RenderWindow ogre_window(hInst);
ogre_window.setDevice(al_get_d3d_device(al_display)); // Function only takes an Ogre::D3D9Device
return 0;
}
It's possible if you use OpenGL. An example comes with Allegro.
Not sure about D3D.
After much work and tedious studying with the help of Matthew's answer I was able to find the solution to the problem through a few pointers on pointers.
Here is the final code:
int _tmain(int argc, _TCHAR* argv[])
{
ALLEGRO_DISPLAY *al_display = NULL;
if(!al_init())
{
fprintf(stderr, "Cannot initialize allegro");
return -1;
}
al_display = al_create_display(640, 480);
if(!al_display)
{
fprintf(stderr,"Cannot initialize the display");
return -1;
}
HWND hWnd = al_get_win_window_handle(al_display);
HINSTANCE hInst = (HINSTANCE)GetWindowLong( hWnd, GWL_HINSTANCE);
Ogre::D3D9RenderWindow ogre_window(hInst);
LPDIRECT3DDEVICE9 D3dDev = al_get_d3d_device(al_display);
IDirect3DDevice9 *iD3dDev = D3dDev;
Ogre::D3D9DeviceManager D3dDevManager;
Ogre::D3D9Device *OD3dDev = D3dDevManager.getDeviceFromD3D9Device(iD3dDev);
ogre_window.setDevice(OD3dDev);
return 0;
}

Running a function when user stops entering text

I am writing a small GUI application using Haskell's gtk2hs library and am currently working with the multiline text boxes within it. I have a function which I want to run when the user makes changes to the text within the text box, but don't want them to have to click a button to activate it.
Furthermore, because it is a rather intrusive and processing intensive function (It draws graphics, loads files etc.), I would like it to fire not whenever a user makes any change (which could probably be done with the bufferChanged signal in text buffer I'm guessing?) but when they stop for a few seconds in between changes.
Basically I am wondering if there is something in gtk which is analogous to the way range widgets can have their update policy set to continuous or delayed, but for text boxes
I don't know anything of the Haskell bindings but in plain C it is quite easy to implement by leveraging a timeout GSource.
#include <gtk/gtk.h>
static guint source_id = 0;
static gboolean do_stuff(gpointer user_data)
{
g_print("doing stuff...\n");
return FALSE;
}
static void postpone(void)
{
if (source_id > 0)
g_source_remove(source_id);
source_id = g_timeout_add(1000, do_stuff, NULL);
}
int main(int argc, char **argv)
{
GtkWidget *window, *text_view;
GtkTextBuffer *text_buffer;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
text_view = gtk_text_view_new();
gtk_container_add(GTK_CONTAINER(window), text_view);
text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
g_signal_connect(text_buffer, "changed", G_CALLBACK(postpone), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
The issue of quitting the TextView before the timeout has elapsed is still open though.

How do I output installation status using gtk in c?

int main( int argc,
char *argv[] )
{
GtkWidget *window;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_show (window);
gtk_main ();
return 0;
}
The above is just a empty winform,I want to output dynamic information in it(not editable),
how should I do that?
You need a GtkTextView which you can set to be not editable. I suggest you look at this excellent GTK tutorial which explains what widgets are available in GTK and how to put them together, accompanied by lots of example code.

Resources