Load Gif into Gtk 3 Window C\C++ - c

I'm trying to create a c application with code::block that use Gtk 3 as a graphics library
This version of gtk is a bit different from gtk 2 and not so much tutorials or exampes are avaiable online. I want to use a type named GdkPixmap that permit to load gifs into your windows, after googled it i have found that the type is deprecated and have been eliminated from gtk new version (3). From official documentation (migrate from gtk2 to gtk3) i have found that is possible to use cairo functions to make the works made by GdkPixmap but i havent found how change and migrate.
This code founded on stackoverflow is an example of loading gif into window using gtk2 that doesnt work on gtk3 compiler said : error unknown type name 'GdkPixmap'
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
GdkPixbuf *load_pixbuf_from_file (const char *filename)
{
GError *error = NULL;
GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file (filename, &error);
if (pixbuf == NULL)
{
g_print ("Error loading file: %d : %s\n", error->code, error->message);
g_error_free (error);
exit (1);
}
return pixbuf;
}
GdkPixbufAnimation *load_pixbuf_animation_from_file (const char *filename)
{
GError *error = NULL;
GdkPixbufAnimation *pixbuf = gdk_pixbuf_animation_new_from_file (filename, &error);
if (pixbuf == NULL)
{
g_print ("Error loading file: %d : %s\n", error->code, error->message);
g_error_free (error);
exit (1);
}
return pixbuf;
}
int main (int argc, char **argv)
{
GtkWidget *window = NULL;
GdkPixbuf *image = NULL;
GdkPixbufAnimation * anim = NULL;
GtkWidget *widget = NULL;
GdkPixmap *background = NULL;
GtkStyle *style = NULL;
gtk_init (&argc, &argv);
/* Load a non animated gif */
image = load_pixbuf_from_file ("C://Users//Pcc//Downloads//66.gif");
// widget = gtk_image_new_from_pixbuf (image);
gdk_pixbuf_render_pixmap_and_mask (image, &background, NULL, 0);
style = gtk_style_new ();
style->bg_pixmap [0] = background;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW(window), "Load Image");
gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
gtk_widget_set_style (GTK_WIDGET(window), GTK_STYLE (style));
gtk_window_set_transient_for (GTK_WINDOW (window), NULL);
GtkWidget *hbox = NULL;
hbox = gtk_hbox_new (0, FALSE);
gtk_container_add (GTK_CONTAINER(window), hbox);
GtkWidget *button = NULL;
button = gtk_button_new_with_label ("Sonic");
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}
Use and install a obsolete gtk i dont think is good
Please to post examples of code that works on gtk3 that load gifs

There's a specific GdkPixmap to Cairo migration guide right inside the official GTK 3 documentation.

Related

how to change multiple widgets property on button click GTK c

I am trying to make UI using GTK in c for raspberry pi 4. I want to change the visibility of different widgets based on button click just to simulate a new page. I have tried everything available on the internet but as I am not that good at coding I cant figure out what is wrong.
can someone please help ?
This program compiles but when I press the button it gives error " assertion failed on gtk_widget_show " and also on widget hide. Also a segmentation fault occurs and the program crashes.
I am using cmake to compile my code. I have attached the error screen shot.
#include <gtk/gtk.h>
typedef struct AppData
{
GtkWidget *label1;
GtkWidget *label2;
} AppData;
static void button1 (gpointer data)
{
AppData *data2 = (AppData*)data;
gtk_widget_hide(data2->label1);
gtk_widget_show(data2->label2);
}
static void button2 ( gpointer data)
{
AppData *data2 = (AppData*)data;
gtk_widget_show(data2->label1);
gtk_widget_hide(data2->label2);
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *fixed;
GtkWidget *btn1;
GtkWidget *btn2;
GtkWidget *box1;
GtkWidget *box2;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "ethercat test 1");
gtk_window_set_default_size(GTK_WINDOW(window), 1000,500);
fixed = gtk_fixed_new();
gtk_container_add(GTK_CONTAINER(window), fixed);
box1 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
gtk_fixed_put(GTK_FIXED(fixed), box1, 0,0);
box2 = gtk_box_new(GTK_ORIENTATION_VERTICAL, 1);
gtk_fixed_put(GTK_FIXED(fixed), box2, 100,100);
AppData *app_data = g_new0 (AppData, 2);
app_data->label1 = gtk_label_new("label1");
gtk_box_pack_start(GTK_BOX(box1),app_data->label1, TRUE,TRUE,0);
app_data->label2 = gtk_label_new("label2");
gtk_box_pack_start(GTK_BOX(box2),app_data->label2, TRUE,TRUE,0);
btn1 = gtk_button_new_with_label("ethercat 1");
gtk_fixed_put(GTK_FIXED(fixed), btn1, 10, 450);
gtk_widget_set_size_request(btn1, 80,30);
btn2 = gtk_button_new_with_label("ethercat 2");
gtk_fixed_put(GTK_FIXED(fixed), btn2, 110, 450);
gtk_widget_set_size_request(btn2, 80,30);
gtk_widget_show_all(window);
g_signal_connect(G_OBJECT(btn1), "clicked", G_CALLBACK(button1), app_data);
g_signal_connect(G_OBJECT(btn2), "clicked", G_CALLBACK(button2), app_data);
g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
printf("program end\n");
return (0);
}
enter image description here
The function signature of your "clicked" callbacks is wrong. It should be of the form as described in the documentation:
void on_clicked(
GtkButton* self,
gpointer user_data
)
So for example, your button2() function becomes
static void button2 (GtkButton *btn2, gpointer data)
{
AppData *data2 = (AppData*)data;
gtk_widget_show(data2->label1);
gtk_widget_hide(data2->label2);
}

How to create a cairo object within a gtk window in GTK+3

I'm trying to use cairo to draw some arcs but gcc warns me that gdk_cairo_create() is deprecated. Use gdk_window_begin_draw_frame() and gdk_drawing_context_get_cairo_context() instead.
To get around this I did some research and found out that for gdk_window_begin_draw_frame() I need "GdkWindow".I've always been using GtkWidget for my windows so I need to convert "GtkWidget" to "GdkWindow", but gtk_widget_get_window() returns NULL and causes segfault.
#include <gtk/gtk.h>
#include <cairo.h>
void main(int argc , char **argv){
gtk_init(&argc , &argv);
GtkWidget *win;
GdkWindow *gdkwin;
GdkDrawingContext *dc;
cairo_region_t *region;
cairo_t *cr;
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
region = cairo_region_create();
gdkwin = gtk_widget_get_window(GTK_WIDGET(win));
//Here gdkwin should contain a GdkWindow but it's NULL.
gc = gdk_window_begin_draw_frame(gdkwin , (const cairo_region_t*)&region);
...
...
Here's the runtime errors:
(a.out:6852): Gdk-CRITICAL **: 23:53:06.042: gdk_window_begin_draw_frame: assertion 'GDK_IS_WINDOW (window)' failed
(a.out:6852): Gdk-CRITICAL **: 23:53:06.042: gdk_drawing_context_get_cairo_context: assertion 'GDK_IS_DRAWING_CONTEXT (context)' failed
Segmentation fault
I want to get a cairo object and use it for cairo_arc().
Thanks.Best regards.
The below is the complete source code to get Cairo working under GTK 3. It should be compilable as is.
As the others already pointed out, you have to use the draw signal to make things work.
#include <gtk/gtk.h>
#include <cairo.h>
// ------------------------------------------------------------
gboolean on_draw (GtkWidget *widget,
GdkEventExpose *event,
gpointer data)
{
// "convert" the G*t*kWidget to G*d*kWindow (no, it's not a GtkWindow!)
GdkWindow* window = gtk_widget_get_window(widget);
cairo_region_t * cairoRegion = cairo_region_create();
GdkDrawingContext * drawingContext;
drawingContext = gdk_window_begin_draw_frame (window,cairoRegion);
{
// say: "I want to start drawing"
cairo_t * cr = gdk_drawing_context_get_cairo_context (drawingContext);
{ // do your drawing
cairo_move_to(cr, 30, 30);
cairo_set_font_size(cr,15);
cairo_show_text(cr, "hello world");
}
// say: "I'm finished drawing
gdk_window_end_draw_frame(window,drawingContext);
}
// cleanup
cairo_region_destroy(cairoRegion);
return FALSE;
}
// ------------------------------------------------------------
int main (int argc, char * argv[]) {
gtk_init(&argc, &argv);
GtkWindow * window;
{ // window setup
window = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (window, 200, 200);
gtk_window_set_position (window, GTK_WIN_POS_CENTER);
gtk_window_set_title (window, "Drawing");
g_signal_connect(window, "destroy", gtk_main_quit, NULL);
}
// create the are we can draw in
GtkDrawingArea* drawingArea;
{
drawingArea = (GtkDrawingArea*) gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), (GtkWidget*)drawingArea);
g_signal_connect((GtkWidget*)drawingArea, "draw", G_CALLBACK(on_draw), NULL);
}
gtk_widget_show_all ((GtkWidget*)window);
gtk_main();
return 0;
}
// ------------------------------------------------------------
In GTK+ 3, you're supposed to do your drawing in response to the draw signal. Doing it in the main makes no sense (the widgets have just been created, but initializing them further in done when running the main event loop).
Please read: https://developer.gnome.org/gtk3/stable/chap-drawing-model.html
The Dark Trick's program is complete.
He uses the functions as follows,
GdkWindow* window = gtk_widget_get_window (widget);
cairo_region_t *cairoRegion = cairo_region_create();
GdkDrawingContext *drawingContext;
drawingContext = gdk_window_begin_draw_frame (window, cairoRegion);
cairo_t *cr = gdk_drawing_context_get_cairo_context (drawingContext);
But I am using the the functions as follows,
GdkWindow *window = gtk_widget_get_window(widget);
cairo_rectangle_int_t cairoRectangle = {0, 0, 200, 200};
cairo_region_t *cairoRegion = cairo_region_create_rectangle (&cairoRectangle);
GdkDrawingContext *drawingContext;
drawingContext = gdk_window_begin_draw_frame (window,cairoRegion);
cairo_t *cr = gdk_drawing_context_get_cairo_context (drawingContext);
This worked, but I can not understand the differencies, for I am an OldUrologist.
I'm not positive, but I think you're trying to get the GdkWindow before it is ready. I think you need to connect to the window's "realize" signal, and only when that signal has been emitted should you try to access the underlying GdkWindow.
#include <gtk/gtk.h>
#include <cairo.h>
void OnWindowRealize(GtkWidget *pWidget, gpointer data)
{
GdkWindow *pUnderlyingWindow = gtk_widget_get_window(pWidget);
cairo_region_t *region = cairo_region_create();
GdkDrawingContext *gc = gdk_window_begin_draw_frame(pUnderlyingWindow, (const cairo_region_t*)&region);
//etc...
}
void main(int argc , char **argv)
{
gtk_init(&argc , &argv);
GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(G_OBJECT(win), "realize", OnWindowRealize, NULL);
//etc...
}

C and GTK g_signal_connect Passing parameters

Cannot get g_signal_connect to pass parameters correctly. Its probably because I do not understand the "c_handler" or "data" parameters. The code is here:
#include <gtk/gtk.h>
// Function prototypes
void my_file_saveas();
// Function
void my_file_saveas(GtkTextBuffer *buf)
{
// Get the start and end bounds of the buffer
GtkTextIter start, end;
gtk_text_buffer_get_bounds (buf, &start, &end);
}
int main(int argc, char *argv[])
{
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMh;
GtkWidget *saveasMi;
GtkWidget *view;
GtkTextBuffer *buffer;
GtkWidget *scroll_window;
GtkWidget *vbox;
GtkWidget *window;
// Call this function first
gtk_init(&argc, &argv);
// Create widgets
menubar = gtk_menu_bar_new();
fileMenu = gtk_menu_new();
fileMh = gtk_menu_item_new_with_label("File");
saveasMi = gtk_menu_item_new_with_label("Save As");
view = gtk_text_view_new();
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
// Set out the menubar
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveasMi);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMh), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMh);
// Create a scroll window and add the view to it
scroll_window = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add(GTK_CONTAINER(scroll_window), view);
// Create a vertical box and add the menubar and scroll_window
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), scroll_window, TRUE, TRUE, 0);
// Setup top level window
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), 640, 480);
// Put the box in the top level window
gtk_container_add(GTK_CONTAINER(window), vbox);
// Events
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(saveasMi), "activate", G_CALLBACK(my_file_saveas), buffer);
// Display the window
gtk_widget_show_all(window);
// Runs main
gtk_main();
return 0;
}
It compiles OK. But the output when I run it is here:
graeme#graeme-HP-xw4300-Workstation ~/c/test $ ./ed10
(ed10:2974): Gtk-CRITICAL **: gtk_text_buffer_get_bounds: assertion 'GTK_IS_TEXT_BUFFER (buffer)' failed
Your error is self-explanatory (kind of):
(debugsig:26923): Gtk-CRITICAL **: gtk_text_buffer_get_bounds:
assertion 'GTK_IS_TEXT_BUFFER (buffer)' failed
Looking at your code -- you do not declare an independent GTK_TEXT_BUFFER (e.g. GtkTextBuffer *). gtk_text_view_new will provide a default buffer, but you can alternatively use gtk_text_view_new_with_buffer (buffer) if you independently declare a buffer with, e.g. gtk_text_buffer_new (NULL); (you will get a default buffer with either gtk_text_view_new or gtk_text_view_new_with_buffer (NULL);). Your choice..., what you have will work.
Your real problem is your callback function prototype is wrong, it should contain your menuitem (that is the real issue, it is taking your buffer as a GtkMenuItem causing the error 'GTK_IS_TEXT_BUFFER (buffer)' failed), e.g.
void my_file_saveas (GtkMenuItem *menuitem, gpointer data)
{
// Get the start and end bounds of the buffer
GtkTextBuffer *buf = GTK_TEXT_BUFFER (data);
GtkTextIter start, end;
gtk_text_buffer_get_bounds (buf, &start, &end);
/* print the number of lines to stdout */
g_print ("Buffer has %d lines.\n", gtk_text_iter_get_line (&end) -
gtk_text_iter_get_line (&start) + 1);
if (menuitem) {} /* stub to suppress warning of unused menuitem */
}
Candidly, I cannot believe it let you compile without error (or warning), but it did, I compiled with:
gcc -Wall -Wextra -pedantic -finline-functions -std=gnu11 ...
and it let me compile with the incorrect prototype too -- wrapped me around the axle for a bit :)
Here is a working example of your code:
#include <gtk/gtk.h>
// Function
void my_file_saveas (GtkMenuItem *menuitem, gpointer data)
{
// Get the start and end bounds of the buffer
GtkTextBuffer *buf = GTK_TEXT_BUFFER (data);
GtkTextIter start, end;
gtk_text_buffer_get_bounds (buf, &start, &end);
g_print ("Buffer has %d lines.\n", gtk_text_iter_get_line (&end) -
gtk_text_iter_get_line (&start) + 1);
if (menuitem) {} /* stub to suppress warning of unused menuitem */
}
int main(int argc, char *argv[])
{
GtkWidget *menubar;
GtkWidget *fileMenu;
GtkWidget *fileMh;
GtkWidget *saveasMi;
GtkWidget *view;
GtkTextBuffer *buffer = NULL;
GtkWidget *scroll_window;
GtkWidget *vbox;
GtkWidget *window;
// Call this function first
gtk_init(&argc, &argv);
// Create widgets
menubar = gtk_menu_bar_new();
fileMenu = gtk_menu_new();
fileMh = gtk_menu_item_new_with_label("File");
saveasMi = gtk_menu_item_new_with_label("Save As");
/** example declaring independent buffer
*
* buffer = gtk_text_buffer_new (NULL);
* view = gtk_text_view_new_with_buffer(buffer);
*/
view = gtk_text_view_new();
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
if (!view || !buffer) {
g_print ("error - no view or buf.\n");
return 1;
}
// Set out the menubar
gtk_menu_shell_append(GTK_MENU_SHELL(fileMenu), saveasMi);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(fileMh), fileMenu);
gtk_menu_shell_append(GTK_MENU_SHELL(menubar), fileMh);
// Create a scroll window and add the view to it
scroll_window = gtk_scrolled_window_new (NULL, NULL);
gtk_container_add(GTK_CONTAINER(scroll_window), view);
// Create a vertical box and add the menubar and scroll_window
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(vbox), scroll_window, TRUE, TRUE, 0);
// Setup top level window
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), 640, 480);
// Put the box in the top level window
gtk_container_add(GTK_CONTAINER(window), vbox);
// Events
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(G_OBJECT(saveasMi), "activate", G_CALLBACK(my_file_saveas),
buffer);
// Display the window
gtk_widget_show_all(window);
// Runs main
gtk_main();
return 0;
}
If you want to look at a bit of a larger example (GTK+2, but 100% applicable here), take a look at https://github.com/drankinatty/gtkwrite. (The textview and buffer declarations are in gtk_windef.c)

GTK+ notebook - unable to print current label text

Hello everyone,
I'm currently trying to convert my PyGTK application to C, everything was
working as expected until I hit an issue with retrieving label name of my notebook widget.
Below is a short example of what I'm trying to achieve..
GtkBuilder *builder = NULL;
GtkWidget *window = NULL;
GtkWidget *notebook = NULL;
GError *error = NULL;
void on_page_switch(GtkNotebook *notebook, gpointer data)
{
// gtk_notebook_get_tab_label_text(GtkNotebook *notebook,GtkWidget *child)
}
int main (int argc, char *argv[])
{
gtk_init (&argc, &argv);
builder = gtk_builder_new ();
if( ! gtk_builder_add_from_file( builder, "data/glade.glade", &error ) )
{
g_warning( "%s", error->message );
g_free( error );
return( 1 );
}
window = GTK_WIDGET (gtk_builder_get_object (builder, "window1"));
gtk_window_set_resizable (GTK_WINDOW(window), FALSE);
g_signal_connect(window, "destroy", GTK_SIGNAL_FUNC (on_window_destroy), NULL);
notebook = GTK_WIDGET (gtk_builder_get_object (builder, "notebook1"));
g_signal_connect(GTK_NOTEBOOK (notebook), "switch-page", GTK_SIGNAL_FUNC(on_page_switch), NULL);
gtk_builder_connect_signals (builder, NULL);
g_object_unref (G_OBJECT (builder));
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
Could you please give me some pointers as how to get the current tab's label name?
I believe it should be this function gtk_notebook_get_tab_label_text(GtkNotebook *notebook, GtkWidget *child) , however I was unable to get it working too.
Apologies for my bad english.
Thanks in advance,
Alex
/// EDIT ////
It was actualy the call-back function it self that was wrong..
I have missed couple of pointers that are passed with the "switch-page" event.
void on_page_switch(GtkNotebook * notebook, GtkWidget *page, guint page_num, gpointer user_data)
{
GtkWidget * child = gtk_notebook_get_nth_page(notebook, page_num);
printf(" -> %i \n", gtk_notebook_page_num(notebook, child));
}
Correct, you should be able to use gtk_notebook_get_tab_label_text() to do this.
You need a pointer to the child widget (page content) whose label you're interested in, you can use gtk_notebook_get_nth_page() to get that if you don't have the notebook children handy.
It's hard to help more since you didn't specify what problems you ran in to when you tried it.

Draw an image on drawing area

I am trying to draw an image on a drawing area with no luck.I saw a couple of python examples but I was not able to implement them into c ,which I am using (eg draw an image to gtk.DrawingArea?)
I have already created a Pixbuf variable to store the image I want to draw on the drawing area,but there are no functions like gtk_drawing_area_draw_pixbuf or something related to that.Any suggestion is appreciated.
You need to make use of expose-event callback (assuming you are working with Gtk+ 2.0) to draw the pixbuf onto drawing area. There is no gtk_drawing_area_draw_pixbuf instead you have gdk_draw_pixbuf. This has been deprecated in favour of gdk_cairo_set_source_pixbuf from version 2.22 onwards. You can call these function in your expose event callback something on these lines (please use them as reference only):
If your Gtk version is < 2.22
static gboolean
da_expose (GtkWidget *da, GdkEvent *event, gpointer data)
{
(void)event; (void)data;
GdkPixbuf *pix;
GError *err = NULL;
/* Create pixbuf */
pix = gdk_pixbuf_new_from_file("/usr/share/icons/cab_view.png", &err);
if(err)
{
printf("Error : %s\n", err->message);
g_error_free(err);
return FALSE;
}
GdkDrawable *draw = gtk_widget_get_window(da);
/* Draw pixbuf */
gdk_draw_pixbuf(draw, NULL, pix, 0, 0, 0, 0, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
return FALSE;
}
Version 2.22 onwards you will have to make use of cairo something on these lines:
static gboolean
da_expose (GtkWidget *da, GdkEvent *event, gpointer data)
{
(void)event; (void)data;
GdkPixbuf *pix;
GError *err = NULL;
/* Create pixbuf */
pix = gdk_pixbuf_new_from_file("/usr/share/icons/cab_view.png", &err);
if(err)
{
printf("Error : %s\n", err->message);
g_error_free(err);
return FALSE;
}
cairo_t *cr;
cr = gdk_cairo_create (da->window);
gdk_cairo_set_source_pixbuf(cr, pix, 0, 0);
cairo_paint(cr);
cairo_fill (cr);
cairo_destroy (cr);
return FALSE;
}
Of course you would have connected to the callback using g_signal_connect (say g_signal_connect (da, "expose-event", G_CALLBACK (da_expose), NULL);). If you are using Gtk+ 3.0 then you will be making use of draw instead of expose-event. You can always refer to gtk-demo/gtk3-demo application which are available to see the samples along with the code. This should be available in the package repository of your distro or you can always get it from source.
Hope this helps!
PS: This link might provide you with some pointers
Now GTK-version is GTK+3.0.
If you are using GTK+3.0, please use as follows.
// gcc expose.c -o expose `pkg-config gtk+-3.0 --cflags --libs`
#include <gtk/gtk.h>
#include <stdlib.h>
static gboolean
on_window_draw (GtkWidget *da, GdkEvent *event, gpointer data)
{
(void)event; (void)data;
GdkPixbuf *pix;
GError *err = NULL;
/* Create pixbuf */
pix = gdk_pixbuf_new_from_file("/usr/share/icons/cab_view.png", &err);
if(err)
{
printf("Error : %s\n", err->message);
g_error_free(err);
return FALSE;
}
cairo_t *cr;
cr = gdk_cairo_create (gtk_widget_get_window(da));
// cr = gdk_cairo_create (da->window);
gdk_cairo_set_source_pixbuf(cr, pix, 0, 0);
cairo_paint(cr);
// cairo_fill (cr);
cairo_destroy (cr);
// return FALSE;
}
int main ( int argc, char **argv) {
GtkWidget *window;
GtkWidget *canvas;
gtk_init (&argc , &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request (window,
50, 50);
g_signal_connect (window, "destroy",
G_CALLBACK (gtk_main_quit) , NULL);
canvas = gtk_drawing_area_new ();
gtk_container_add (GTK_CONTAINER (window), canvas);
g_signal_connect (canvas, "draw", (GCallback) on_window_draw, NULL);
gtk_widget_set_app_paintable(canvas, TRUE);
gtk_widget_show_all (window);
gtk_main ();
return 0;
}

Resources