2 problems: make argument for gdk_cairo_create and how do I fix my expose event?
My c configure event callback function receives as its first argument the pointer drawing_area, created by drawing_area = gtk_drawing_area_new();
Time to draw! Looks like I need to use
cairo_t * gdk_cairo_create (GdkDrawable *drawable);
Please, how? How do I convert or extract a GdkDrawable from my drawing_area?
Also, I when i run my program, ... I'll just include it along with the output. Thank you, Dave.
Code:
#include<gtk/gtk.h>
GdkPixbuf*create_pixbuf(const gchar*filename) {
GdkPixbuf*pixbuf;
GError*error = NULL;
pixbuf = gdk_pixbuf_new_from_file(filename, &error);
if(!pixbuf) {
fprintf(stderr,"\n%s\n", error->message);
g_error_free(error);
}
return pixbuf;
}
void draw(GtkWidget*widget,gpointer data) {
cairo_t*cr;
if (data != (gpointer)widget) {
fputs("\ndraw request at unexpected widget\n",stderr);
}
cr = gdk_cairo_create(GDK_WINDOW(widget));
}
static gboolean configure_event(GtkWidget*widget,const GdkEvent*event,gpointer data) {
puts("configure");
draw(widget,data);
return TRUE;
}
static gboolean expose_event(GtkWidget*widget,const GdkEvent*event,gpointer data) {
puts("expose");
draw(widget,data);
return TRUE;
}
static gboolean button_press_event(GtkWidget*widget,const GdkEvent*event,gpointer data) {
gdouble x_win, y_win;
if (!gdk_event_get_coords(event,&x_win,&y_win))
puts("BUTTON, gdk_event_get_coords(event,&x_win,&y_win)) failed");
else
printf("x_win=%g y_win=%g\n",(double)x_win,(double)y_win);
draw(widget,data);
return TRUE;
}
static gboolean key_press_event(GtkWidget*widget,const GdkEvent*event,gpointer data) {
guint keyval;
if (gdk_event_get_keyval(event,&keyval))
printf("key with unicode value: %d\n",(int)gdk_keyval_to_unicode(gdk_keyval_to_upper(keyval)));
else
puts("KEY! gdk_event_get_keyval(event,&keyval)) failed.");
draw(widget,data);
return TRUE;
}
int main(int argc,char*argv[]) {
/* discovery: GtkWidget handles just about everything! */
GtkWidget *window, *vbox, *label, *drawing_area;
GRand*random_numbers = g_rand_new();
/* discovery: gtk_init removes gtk debug flags, such as --gtk-debug=all */
/* guess: probably also calls gdk_init which handles --display and --screen or other X11 communication issues */
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* discovery: GTK_WINDOW(GtkWidget*) casts the widget to window */
/* discovery: window in the function name? use GTK_WINDOW. g_ in function name? use G_OBJECT */
gtk_window_set_title(GTK_WINDOW(window), "Rosetta Code Honeycomb, C with GTK");
gtk_window_set_default_size(GTK_WINDOW(window), 308, 308+12+8); /* XxY */
/* discovery: making the window vanish does not stop the program */
/* discovery: NULL is placeholder for extra data sent to the callback */
g_signal_connect_swapped(G_OBJECT(window),"destroy",G_CALLBACK(gtk_main_quit),NULL);
/* I created /tmp/favicon.ico from http://rosettacode.org/favicon.ico */
/* Your window manager could use the icon, if it exists */
/* Otherwise, no biggie */
gtk_window_set_icon(GTK_WINDOW(window), create_pixbuf("/tmp/favicon.ico"));
vbox = gtk_vbox_new(TRUE,1);
gtk_container_add(GTK_CONTAINER(window), vbox);
label = gtk_label_new("None Selected");
gtk_widget_set_size_request(label,308,20);
gtk_box_pack_end(GTK_BOX(vbox),label,FALSE,TRUE,4);
drawing_area = gtk_drawing_area_new();
gtk_widget_set_events(drawing_area,GDK_BUTTON_PRESS_MASK|GDK_KEY_PRESS_MASK|GDK_EXPOSURE_MASK);
g_signal_connect(G_OBJECT(drawing_area),"expose_event",G_CALLBACK(expose_event),(gpointer)drawing_area);
g_signal_connect(G_OBJECT(drawing_area),"configure_event",G_CALLBACK(configure_event),(gpointer)drawing_area);
g_signal_connect(G_OBJECT(drawing_area),"button_press_event",G_CALLBACK(button_press_event),(gpointer)drawing_area);
g_signal_connect(G_OBJECT(drawing_area),"key_press_event",G_CALLBACK(key_press_event),(gpointer)drawing_area);
gtk_widget_set_size_request(drawing_area, 308, 308); /* XxY */
gtk_box_pack_start(GTK_BOX(vbox),drawing_area,TRUE,TRUE,4);
/* Discovery: must allow focus to receive keyboard events */
gtk_widget_set_can_focus(drawing_area,TRUE);
/* Discovery: can set show for individual widgets or use show_all */
gtk_widget_show_all(window);
gtk_main();
g_rand_free(random_numbers);
return 0;
}
Compilation and output:
Code:
-*- mode: compilation; default-directory: "/tmp/" -*-
Compilation started at Tue Mar 27 22:54:00
a=./hexagon && make -k "CFLAGS=$( pkg-config --cflags gtk+-3.0 )" "LOADLIBES=$( pkg-config --libs gtk+-3.0 )" $a && $a --gtk-debug=all
cc -pthread -DGSEAL_ENABLE -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng12 -I/usr/include/gtk-3.0 hexagon.c -pthread -lgtk-3 -lgdk-3 -latk-1.0 -lcairo-gobject -lgio-2.0 -lpangoft2-1.0 -lpangocairo-1.0 -lgdk_pixbuf-2.0 -lcairo -lpango-1.0 -lfreetype -lfontconfig -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lrt -lglib-2.0 -o hexagon
[color=#FF0040](hexagon:24426): GLib-GObject-WARNING **: /build/buildd/glib2.0-2.30.0/./gobject/gsignal.c:2295: signal `expose_event' is invalid for instance `0x10678c0'
configure[/color]
(hexagon:24426): GLib-GObject-WARNING **: invalid cast from `GtkDrawingArea' to `GdkWindow'
(hexagon:24426): Gdk-CRITICAL **: gdk_cairo_create: assertion `GDK_IS_WINDOW (window)' failed
configure
(hexagon:24426): GLib-GObject-WARNING **: invalid cast from `GtkDrawingArea' to `GdkWindow'
(hexagon:24426): Gdk-CRITICAL **: gdk_cairo_create: assertion `GDK_IS_WINDOW (window)' failed
configure
(hexagon:24426): GLib-GObject-WARNING **: invalid cast from `GtkDrawingArea' to `GdkWindow'
(hexagon:24426): Gdk-CRITICAL **: gdk_cairo_create: assertion `GDK_IS_WINDOW (window)' failed
x_win=239 y_win=94
(hexagon:24426): GLib-GObject-WARNING **: invalid cast from `GtkDrawingArea' to `GdkWindow'
(hexagon:24426): Gdk-CRITICAL **: gdk_cairo_create: assertion `GDK_IS_WINDOW (window)' failed
Compilation finished at Tue Mar 27 22:54:04