Change window title - `GTK_IS_WINDOW (window)' failed - c

I want to change titlie of main window of my C/gtk+ application. I have code:
void update_title(const char *filename, MainWin* mw )
{
GtkButton* btn = gtk_button_new();
static int wid, hei;
static char fname[50];
char buf[100];
if(filename != NULL)
{
strncpy(fname, filename, 49);
wid = gdk_pixbuf_get_width( gtk_image_view_get_pixbuf (GTK_IMAGE_VIEW(aview)) );
hei = gdk_pixbuf_get_height( gtk_image_view_get_pixbuf ( GTK_IMAGE_VIEW(aview)) );
fname[49] = '\0';
}
snprintf(buf, 100, "%s (%dx%d) %d%%", fname, wid, hei, (int)(mw->scale * 100));
gtk_window_set_title(mw, buf);
}
When i try to call this function i see error: Gtk-CRITICAL **: gtk_window_set_title: assertion `GTK_IS_WINDOW (window)' failed
What's wrong?
Thank you.

mw is of MainWin type, gtk_window_set-title() expect a GtkWindow type.

You are repeatidly asking the same question and you'll repeatedly receive the same answer. These are your options:
Learn how to properly subclass a GObject
Write a proper question, such as I'm trying to subclass a GtkWindow with this code but...
Goto 1.

Related

Probleme with structure, string anf gtkwidget

I'm trying to create a diaporama in c using gtk. I have a button "previous", which show the previous image. So I connect my button to a function and I pass it to a structure. But when I try to print an element of my array I have weird characters, and I don't know why. Plus, I got this warning for my gtk image :
GLib-GObject-WARNING **: 19:12:16.442: invalid uninstantiatable type '(null)' in cast to 'GtkImage'
Gtk-CRITICAL **: 19:12:16.442: IA__gtk_image_set_from_file: assertion 'GTK_IS_IMAGE (image)' failed
Here's my structure :
struct ButtonsArg {
GtkWidget *image;
char *img[];
};
Here's my code for the initialisation of my structure in the main :
GtkWidget *image = gtk_image_new();
char *images[nbImages];
//I get the name of all my image in this function
getImageList(images);
//This print work fine
printf("%s\n", images[0]);
struct ButtonsArg * arg;
arg = malloc(sizeof(struct ButtonsArg) + nbImages*sizeof(char*));
for(int i = 0; i < nbImages; i++) {
arg->img[i] = malloc(strlen(images[i])+1);
strcpy(arg->img[i], images[i]);
}
arg->image = image;
g_signal_connect(precedent, "clicked", G_CALLBACK(event_precedent), &arg);
Here's the function where the problems occur:
static void event_previous(GtkWidget *widget, gpointer data) {
g_print ("previous\n");
struct ButtonsArg *arg = data;
//Print weird charac
for(int i = 0; i < nbImages; i++) {
printf("%s\n", arg->img[i]);
}
GtkWidget *image = arg->image;
if(currentImage == 0) {
currentImage = nbImages - 1;
gtk_image_set_from_file (GTK_IMAGE (arg->image), arg->img[1]);
} else {
currentImage--;
gtk_image_set_from_file (GTK_IMAGE (arg->image), arg->img[2]);
}
}
If you have any advice, help or link that could help, thanks for sharing it with me.
Can you show the part of code where you try to change GtkImage variable? Seems like program was trying to set the null-value to GtkImage-type variable. In this cause any expression with this variable (like image->value) can raise segementation fault.
UPD: Ok. I see it. You should be check the arg-structure. I think, some attribute of this structure can have null-value.

Hooking function with "::" in C library loaded by LD_PRELOAD

I want to code a function called "CSys::Printf" using LD_Preload, but I think it would not be so easy, as in C you can't have "::" in function name, that would be needed to match the original function name.
A piece of the code used to hook would be like this:
int CSys::Printf(const char *format, ...) {
void *handle;
char *error;
if (conprint == NULL) {
handle = dlopen("dedicated.so", RTLD_LAZY);
if (!handle) {
fputs(dlerror(), stderr);
exit(1);
}
conprint = (int (*)(const char *format, ...))dlsym(handle, "CSys::Printf");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(1);
}
printf("*HOOK CSys::Printf OK*");
}
Well, this should work at hooking any function except this case, where the compiler won't accept the "::" on function name.
What should I do?
Thanks!

C - Xlib - BadWindow Error using XGetWindowProperty for window title

I want to get a list of all open windows' titles using Xlib in C. I am running Ubuntu 12.04. I am using the following code to accomplish this:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, &len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
Now the problem that I'm having is that this goes through most windows and then gives me a BadWindow error:
0: DNDCollectionWindow
1: launcher
2: Desktop
3: panel
4: Dash
5: Hud
6: Switcher
7: Update Manager
8: Terminal
9: Ask a Question - Stack Overflow - Mozilla Firefox
X Error of failed request: BadWindow (invalid Window parameter)
Major opcode of failed request: 20 (X_GetProperty)
Resource id in failed request: 0x41
Serial number of failed request: 22
Current serial number in output stream: 22
So I'm wondering if anyone knows what is causing this/how to fix it?
As far as I can tell the list function is returning some windows that I can't retrieve the name of, but I'm not sure.
Thanks in advance!
As per my comments, as the code is listed in the question, I get the compiler warning:
In function ‘list’: 14:29: warning: passing argument 10 of
‘XGetWindowProperty’ from incompatible pointer type [enabled by
default]
&type, &form, &len, &remain, &list);
^
In file included ...:
/usr/include/X11/Xlib.h:2688:12: note: expected ‘long unsigned int ’ but argument is of type ‘long unsigned int *’
Which was fixed by removing the address-of operator from the 10th parameter, changing &len to len, as it's being passed to list() as unsigned long *len.
NOTE: in the name() function, as it's declared as unsigned long len, the address-of operator is necessary.
Therefore, I've started with the following code which compiled without warnings:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
int i;
for(i = 0; i < (int)len; i++){
if(wlist[i] != 0){
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
}
}
return 0;
}
Initially I was not getting the BadWindow error, so I inserted a sleep( 3 ) on line 38, just prior to the for loop to give me enough time to close a window in an attempt to replicate the behaviour.
Sure enough, this reproduced the error: BadWindow (invalid Window parameter).
Scanning the code it originally appeared that the if( wlist[i]==0 ) should kick out invalid window handles, but this is not actually the case. Additionally, inserting a if( !window ) test into the name() function itself was equally futile.
However, the function XSetErrorHandler may be of some use, and I've included your code, revised, to show usage:
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <stdio.h>
#include <stdlib.h>
int catcher( Display *disp, XErrorEvent *xe )
{
printf( "Something had happened, bruh.\n" );
return 0;
}
Window *list(Display *disp, unsigned long *len)
{
Atom prop = XInternAtom(disp, "_NET_CLIENT_LIST", False), type;
int form;
unsigned long remain;
unsigned char *list;
XGetWindowProperty(disp, XDefaultRootWindow(disp), prop, 0, 1024, False, XA_WINDOW,
&type, &form, len, &remain, &list);
return (Window *)list;
}
char *name(Display *disp, Window window)
{
Atom prop = XInternAtom(disp, "WM_NAME", False), type;
int form;
unsigned long remain, len;
unsigned char *list;
XGetWindowProperty(disp, window, prop, 0, 1024, False, AnyPropertyType,
&type, &form, &len, &remain, &list);
return (char*)list;
}
int main(int argc, char *argv[])
{
Display *disp;
Window *wlist;
unsigned long len;
char *wname;
disp = XOpenDisplay(NULL);
wlist = (Window*)list(disp, &len);
sleep( 3 ); // <-- inserted to give me time to close an open window
XSetErrorHandler( catcher ); // <-- inserted to set error handler
int i;
for(i = 0; i < (int)len; i++){
// if(wlist[i] != 0){ // <-- apparently futile?
wname = name(disp, wlist[i]);
printf("%d: %s\n", i, wname);
free(wname);
// }
}
XSetErrorHandler( NULL ); // <-- restore the default error handler
return 0;
}
I've simply created a small function int catcher( Display*, XErrorEvent * ) to catch the errors, avoiding runtime termination.
In case you have more coding to follow, I've included a second call to XErrorHandler(), passing NULL to restore the default handler.
A few other notes, first tested this code by killing the last window I created, but that wasn't quite enough to determine if it would proceed after receiving the error. So I did a second test wherein I killed windows that came before the end of the list, and have verified success.
A few final notes:
Obviously the error handler is over-simplified. When the error is caught, the message is displayed, and the program continues to run.
However, the window item is still printed, but is reflected as (null)...
E.G.:
7: neo – Dolphin
8: neo – Dolphin
Something had happened, bruh.
9: (null)
10: neo – Dolphin
Hopefully this can get you started... I'll leave the fun parts, such as detecting which error 'had happened', and adjusting the numbering/display of the list up to you ; )

Error in CloudPebble, "ld returned 1 exit status"

So, I'm trying to make a Pebble app that generates a random string when you press a button. I'm pretty sure I have the Pebble code right, but I'm not sure what to do with this error:
/sdk2/[long stuff here]/ In function `_sbrk_r':
/home/[more long stuff]: undefined reference to `_sbrk'
collect2: error: ld returned 1 exit status
Waf: Leaving directory `/tmp/tmpX94xY7/build'
Build failed
And here's my code:
#include <pebble.h>
#include <stdlib.h>
#include <stdio.h>
Window *window;
TextLayer *text_layer;
char* one[] = {"string1", "stringone", "stringuno"};
char* two[] = {"string2", "stringtwo", "stringdos"};
char* three[] = {"string3", "stringthree", "stringtres"};
char* four[] = {"string4", "stringfour", "stringcuatro"};
int length1 = sizeof(one)/sizeof(*one);
int length2 = sizeof(two)/sizeof(*two);
int length3 = sizeof(three)/sizeof(*three);
int length4 = sizeof(four)/sizeof(*four);
char* gen()
{
char out[256];
sprintf(out, "%s, and then %s %s %s.", one[rand() % length1], two[rand() % length2], three[rand() % length3], four[rand() % length4]);
char* result = malloc(strlen(out) + 1);
strcpy(result, out);
return result;
}
static void select_click_handler(ClickRecognizerRef recognizer, void *context)
{
char* stringGen = gen();
text_layer_set_text(text_layer, stringGen);
free(stringGen);
}
static void click_config_provider(void *context)
{
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
window_single_click_subscribe(BUTTON_ID_UP, select_click_handler);
window_single_click_subscribe(BUTTON_ID_DOWN, select_click_handler);
}
static void window_load(Window *window)
{
Layer *window_layer = window_get_root_layer(window);
GRect bounds = layer_get_bounds(window_layer);
text_layer = text_layer_create((GRect) { .origin = { 0, 72 }, .size = { bounds.size.w, bounds.size.h } });
text_layer_set_text(text_layer, "Press >>>");
text_layer_set_text_alignment(text_layer, GTextAlignmentCenter);
layer_add_child(window_layer, text_layer_get_layer(text_layer));
}
static void window_unload(Window *window)
{
text_layer_destroy(text_layer);
}
void handle_init(void)
{
window = window_create();
window_set_click_config_provider(window, click_config_provider);
window_set_window_handlers(window, (WindowHandlers) {
.load = window_load,
.unload = window_unload,
});
const bool animated = true;
window_stack_push(window, animated);
}
void handle_deinit(void)
{
text_layer_destroy(text_layer);
window_destroy(window);
}
int main(void)
{
handle_init();
app_event_loop();
handle_deinit();
}
I can't figure out why I'm getting that error. It's a simple application, I just have these little tweaks.
Thank you in advance for your help!
According to this (old) FAQ, that error happens when you try to use a C standard library function that hasn't been implemented in the SDK. If you look in the API reference, snprintf is available, but not sprintf. You can replace your call to sprintf in gen with something like
snprintf(out, 256, "%s, and then %s %s %s.", one[rand() % length1], two[rand() % length2], three[rand() % length3], four[rand() % length4]);
I just tried this out and it builds fine.
(As an aside, it may be a better a idea to declare out a global static buffer and just write over it each time, instead of constantly dynamically allocating memory.)

Glade3 and C programming

I am trying to create a simple app that accepts two integer and displays Sum of two on clicking "Sum" button
And I am new to Glade3, so you can expect blunders
/*
* Compile me with:
* gcc -o test test.c $(pkg-config --cflags --libs gtk+-2.0 gmodule-2.0)
*/
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
GtkBuilder *builder;
GtkWidget *window;
GError *error = NULL;
void on_button1_clicked(GtkButton *button1, GtkEntry *entry1, GtkEntry *entry2, GtkEntry *entry3 )
{
const char *input1 = (const char *)malloc(20);
const char *input2 = (const char *)malloc(20);
char *result = (char *)malloc(20);
int input1_int, input2_int, result_int;
g_print ("Check point 1\n"); //to help debugging
input1 = gtk_entry_get_text(entry1); //fetching user data from entry1
input2 = gtk_entry_get_text(entry2); //fetching user data from entry2
g_print ("Check point 2\n"); //to help debugging
input1_int = atoi(input1); // String to Integer Conversion
input2_int = atoi(input2);
result_int = input1_int + input2_int; //Sum operation
sprintf(result, "%d", result_int);
gtk_entry_set_text(entry3, result); //Pushing result of Sum operation into Entry3
}
void on_window1_destroy (GtkObject *object, gpointer user_data)
{
gtk_main_quit();
}
int main( int argc, char **argv )`
{
/* Init GTK+ */
gtk_init( &argc, &argv );
/* Create new GtkBuilder object */
builder = gtk_builder_new();
/* Load UI from file.
* Replace "sum.glade" with your saved project. */
if( ! gtk_builder_add_from_file( builder, "sum.glade", &error ) )
{
g_warning( "%s", error->message );
g_free( error );
return( 1 );
}
/* Get main window pointer from UI */
window = GTK_WIDGET( gtk_builder_get_object( builder, "window1" ) );
/* Connect signals */
gtk_builder_connect_signals( builder, NULL );
/* Destroy builder, since we don't need it anymore */
g_object_unref( G_OBJECT( builder ) );
/* Show window. All other widgets are automatically shown by GtkBuilder */
gtk_widget_show( window );
/* Start main loop */
gtk_main();
return( 0 );
}
Output:
Check point 1
(test:10082): Gtk-CRITICAL **: gtk_entry_get_text: assertion `GTK_IS_ENTRY (entry)' failed Segmentation fault (core dumped)
you are passing 'NULL' for the callback functions here:
gtk_builder_connect_signals( builder, NULL );
Also remember to free memory allocated to *input1, *input2 and *result.
The prototype for the button's clicked signal is wrong. It should be (Reference):
void user_function (GtkButton *button, gpointer user_data)
Probably the best option would be to pass builder into the callback and retrieve the entry widgets from there (unref it after gtk_main) or pass a structure with both widgets.

Resources