Well, it took me some time to get close to the solution,
but I think I am on the good way, I solved the problem by
using thread and not idle functions, the corrected code is
now:
Code:
#include <gtk/gtk.h>
#include <glib/gstdio.h>
#include <pthread.h>
static gboolean configure_event( GtkWidget *widget,
GdkEventConfigure *event );
void quit_application(GtkWidget *w, gpointer user_data);
void on_window_map (GtkWidget*, gpointer);
void on_window_realize (GtkWidget*, gpointer);
void on_window_show (GtkWidget*, gpointer);
static gboolean expose_event( GtkWidget *widget,
GdkEventExpose *event );
void
on_event_after (GtkWidget *widget,
GdkEvent *event,
gpointer user_data);
static GdkPixmap *pixmap = NULL;
int dareaexist=0;
int main_start=0;
GtkWidget *window;
GtkWidget *darea;
void* draw_line(void* arg)
{
GdkEventExpose *event;
char c;
int x1,y1,x2,y2;
int h,w;
c='y';
do
{
if(dareaexist>0)
{
while(getchar()!='\n');
g_printf("Do you want to add a line (y/n) : ");
scanf("%c",&c);
if(c=='y')
{
g_printf("Insert 1st point x y: ");
scanf("%d %d",&x1,&y1);
g_printf("Insert 2nd point x y: ");
scanf("%d %d",&x2,&y2);
gdk_threads_enter();
gdk_draw_line(pixmap,
darea->style->black_gc,
x1,y1,x2,y2
);
gdk_window_get_size(pixmap, &w, &h);
gdk_draw_pixmap(darea->window,
darea->style->fg_gc[GTK_WIDGET_STATE (darea)],
pixmap,
0,
0,
0,
0,
w,
h );
gtk_widget_queue_draw (darea);
gdk_threads_leave();
};
};
}while(c!='n');
gtk_main_quit();
}
static gboolean configure_event( GtkWidget *widget,
GdkEventConfigure *event )
{
if (pixmap)
g_object_unref (pixmap);
pixmap = gdk_pixmap_new (widget->window,
widget->allocation.width,
widget->allocation.height,
-1);
gdk_draw_rectangle (pixmap,
widget->style->white_gc,
TRUE,
0, 0,
widget->allocation.width,
widget->allocation.height);
return TRUE;
}
static gboolean expose_event( GtkWidget *widget,
GdkEventExpose *event )
{
gdk_draw_drawable (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
pixmap,
event->area.x, event->area.y,
event->area.x, event->area.y,
event->area.width, event->area.height);
return FALSE;
}
int
main (int argc, char *argv[])
{
pthread_t tid;
/* initialize the GTK+ library */
g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init (&argc, &argv);
/* create main window */
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Example");
gtk_container_set_border_width (GTK_CONTAINER (window), 0);
gtk_widget_set_size_request (window, 200, 100);
g_signal_connect (G_OBJECT(window), "event-after",
G_CALLBACK (on_event_after), NULL);
gtk_widget_set_size_request(GTK_WIDGET(window),400,400);
gtk_widget_show (window);
pthread_create(&tid,NULL,draw_line,NULL);
gtk_main ();
gdk_threads_leave();
return 0;
}
void quit_application(GtkWidget *w, gpointer user_data)
{
gtk_main_quit();
}
void
on_window_map (GtkWidget *w,gpointer user_data)
{
g_print("Window was mapped.\n");
}
void
on_window_realize (GtkWidget *w,gpointer user_data)
{
g_print("Window was realized.\n");
}
void
on_window_show (GtkWidget *w,gpointer user_data)
{
g_print("Window was shown.\n");
}
void
on_event_after (GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
// g_printf("event type: %d \n",event->type);
if ((event->type == GDK_EXPOSE)&&(main_start==0))
{
char c;
g_printf("Do you want to create a drawing area: ");
scanf("%c",&c);
main_start = 1;
if (c=='y')
{
dareaexist=1;
darea = gtk_drawing_area_new();
gtk_widget_set_size_request(GTK_WIDGET(darea),400,400);
gtk_container_add (GTK_CONTAINER (widget), darea);
g_signal_connect (G_OBJECT (darea),"configure_event",
G_CALLBACK (configure_event), NULL);
g_signal_connect (G_OBJECT (darea), "expose_event",
G_CALLBACK (expose_event), NULL);
gtk_widget_show(darea);
}
}
}
to be compiled with `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
I would like to have opinions about the solution particularly is it correct?
Could I do the same without using threads?
Hints about possible improvements.. i am just learning gtk+ and c together so any advice would be welcome.
Thanx a lot
roscarby