I've done this simple app in Gtk, just to test things out... I come from swing so redefining a draw event function is normal for me... Anyway seems not to work:
#include <gtk-2.0/gtk/gtk.h>
#include <gtk-2.0/gdk-pixbuf/gdk-pixbuf.h>
#include <stdlib.h>
#include<string.h>
#include<stdio.h>
#include <iostream>
GdkPixbuf *imm;
void destroy(GtkWidget *widget, gpointer data) {
gtk_main_quit();
}
gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event,
gpointer data) {
gdk_draw_pixbuf((GdkDrawable*) widget, widget->style->white_gc, imm, 0, 0,
0, 0, -1, -1, GDK_RGB_DITHER_NONE, 0, 0);
return FALSE;
}
int main(int argc, char** argv) {
char* filename = new char[1000];
GError *error = NULL;
GtkWidget *window;
gtk_set_locale();
gtk_init(&argc, &argv);
if (argv[1] == NULL) {
std::cout << "Err.";
return -1;
}
strcpy(filename, argv[1]);
imm = gdk_pixbuf_new_from_file(filename, &error);
if (!imm) {
std::cout << "err closing";
return 0;
}
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request((GtkWidget*) window, 500, 350);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(destroy), NULL);
g_signal_connect(window, "expose-event",
G_CALLBACK(on_expose_event), NULL);
gtk_container_set_border_width(GTK_CONTAINER (window), 10);
gtk_widget_show(window);
gtk_main();
return 0;
}
..in fact at runtinme says (on line gdk_draw_pixbuf(....)):
(cConvolve:5011): Gdk-CRITICAL **: gdk_draw_pixbuf: assertion `GDK_IS_DRAWABLE (drawable)' failed
is it because the pixbuf is not good??? Or is it because I can't draw to the window like this?
It's because you cast GtkWidget to GdkDrawable, whereas GtkWidget doesn't inherit from GdkDrawable. Use
gdk_draw_pixbuf(GDK_DRAWABLE(gtk_widget_get_window(widget)), blah blah...);
Anyway in normal GTK use you don't have to do any drawing in expose handlers. To display an image, just use the GtkImage widget:
GtkImage *image = gtk_image_new_from_file(filename);
gtk_container_add(GTK_CONTAINER(window), image);
Widgets don't inherit from GdkDrawable, you need to get the drawable from the widget's window.
Thanks. But my purpose was to try drawing on the window bg... anyway, even if I dont' get anymore asserts, it doesn't work:
gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event,
gpointer data) {
int w, h;
w = gdk_pixbuf_get_width(imm);
h = gdk_pixbuf_get_height(imm);
gdk_draw_pixbuf((GdkDrawable*) widget->window, widget->style->fg_gc[ GTK_STATE_NORMAL ], imm, 0, 0,
0, 0, w, h, GDK_RGB_DITHER_NORMAL, 0, 0);
return FALSE;
}
Related
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*)®ion);
...
...
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*)®ion);
//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...
}
This follows from my previous question, I am trying to set the mouse cursor to cross hair when hovering over a GtkDrawingArea. I am trying to apply the answer from ebassi to the following code from zetcode. So far I have got:
#include <cairo.h>
#include <gtk/gtk.h>
static void do_drawing(cairo_t *);
struct {
int count;
double coordx[100];
double coordy[100];
} glob;
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
do_drawing(cr);
return FALSE;
}
static void do_drawing(cairo_t *cr)
{
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 0.5);
int i, j;
for (i = 0; i <= glob.count - 1; i++ ) {
for (j = 0; j <= glob.count - 1; j++ ) {
cairo_move_to(cr, glob.coordx[i], glob.coordy[i]);
cairo_line_to(cr, glob.coordx[j], glob.coordy[j]);
}
}
glob.count = 0;
cairo_stroke(cr);
}
static gboolean
on_crossing (GtkWidget *darea, GdkEventCrossing *event)
{
switch (gdk_event_get_event_type (event))
{
case GDK_ENTER_NOTIFY:
printf("Yey!");
break;
case GDK_LEAVE_NOTIFY:
printf("Whooo!");
break;
}
}
static gboolean clicked(GtkWidget *widget, GdkEventButton *event,
gpointer user_data)
{
if (event->button == 1) {
glob.coordx[glob.count] = event->x;
glob.coordy[glob.count++] = event->y;
}
if (event->button == 3) {
gtk_widget_queue_draw(widget);
}
return TRUE;
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *darea;
glob.count = 0;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_widget_set_has_window (GTK_WIDGET (darea), TRUE);
int crossing_mask = GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
gtk_widget_add_events (GTK_WIDGET (darea), crossing_mask);
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
g_signal_connect (darea, "enter-notify-event", G_CALLBACK (on_crossing), NULL);
g_signal_connect (darea, "leave-notify-event", G_CALLBACK (on_crossing), NULL);
g_signal_connect(G_OBJECT(darea), "draw",
G_CALLBACK(on_draw_event), NULL);
g_signal_connect(window, "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(window, "button-press-event",
G_CALLBACK(clicked), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
gtk_window_set_title(GTK_WINDOW(window), "Lines");
gtk_widget_show_all(window);
gtk_main();
return 0;
}
However, it is not compiling, gcc 5.3.0 tells the error:
undefined reference to `gdk_event_get_event_type'
What am i doing wrong?
I am working on a Win10 machine, using MinGW. I have not tried yet to compile this in a GNU/Linux system.
"Undefined reference" means that you're using a version of GTK+ that does not have gdk_event_get_event_type(). That function was introduced in GTK+ 3.10, as the documentation specifies; 3.10.0 was released in September 2013, so it means you have a version that is at least 4 years older than that, and very much unsupported.
The latest version of GTK+ is, at the time I'm writing this answer, 3.22.12, released in April 2017.
Please, follow the instructions on the GTK+ website on how to install GTK+ on Windows.
Where, in the following zetcode, is the cairo context cr declared?
#include <cairo.h>
#include <gtk/gtk.h>
static void do_drawing(cairo_t *);
struct {
int count;
double coordx[100];
double coordy[100];
} glob;
static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr,
gpointer user_data)
{
do_drawing(cr);
return FALSE;
}
static void do_drawing(cairo_t *cr)
{
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 0.5);
int i, j;
for (i = 0; i <= glob.count - 1; i++ ) {
for (j = 0; j <= glob.count - 1; j++ ) {
cairo_move_to(cr, glob.coordx[i], glob.coordy[i]);
cairo_line_to(cr, glob.coordx[j], glob.coordy[j]);
}
}
glob.count = 0;
cairo_stroke(cr);
}
static gboolean clicked(GtkWidget *widget, GdkEventButton *event,
gpointer user_data)
{
if (event->button == 1) {
glob.coordx[glob.count] = event->x;
glob.coordy[glob.count++] = event->y;
}
if (event->button == 3) {
gtk_widget_queue_draw(widget);
}
return TRUE;
}
int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *darea;
glob.count = 0;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_container_add(GTK_CONTAINER(window), darea);
gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
g_signal_connect(G_OBJECT(darea), "draw",
G_CALLBACK(on_draw_event), NULL);
g_signal_connect(window, "destroy",
G_CALLBACK(gtk_main_quit), NULL);
g_signal_connect(window, "button-press-event",
G_CALLBACK(clicked), NULL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 400, 300);
gtk_window_set_title(GTK_WINDOW(window), "Lines");
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Is cairo context cr automatically declared in the code and associated with the darea (unfortunate name for drawing area) when we call the function
g_signal_connect(G_OBJECT(darea), "draw",
G_CALLBACK(on_draw_event), NULL);
?
The widget will emit the signal and pass it's internal cairo context. When you connect a callback to handle the signal, cairo context is sent by the widget, you receive it and work on it.
Draw signal belongs to Gtk Widget class:
gboolean user_function (GtkWidget *widget, CairoContext *cr, gpointer user_data)
From the draw documentation:
This signal is emitted when a widget is supposed to render itself. The
widget 's top left corner must be painted at the origin of the passed
in context and be sized to the values returned by
gtk_widget_get_allocated_width() and
gtk_widget_get_allocated_height().
Signal handlers connected to this signal can modify the cairo context
passed as cr in any way they like and don't need to restore it. The
signal emission takes care of calling cairo_save() before and
cairo_restore() after invoking the handler.
The signal handler will get a cr with a clip region already set to the
widget's dirty region, i.e. to the area that needs repainting.
Complicated widgets that want to avoid redrawing themselves completely
can get the full extents of the clip region with
gdk_cairo_get_clip_rectangle(), or they can get a finer-grained
representation of the dirty region with
cairo_copy_clip_rectangle_list().
I also hated the CairoContext *cr is
not defined but is simply cairo_t *cr
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 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;
}