/** mousefollow.c **/ #include struct stateStruct { gboolean havePoints; gboolean drawing; gint x; gint y; GdkGC *lineGC; }; gint eventDelete(GtkWidget *widget, GdkEvent *event,gpointer data); gint eventDestroy(GtkWidget *widget, GdkEvent *event,gpointer data); gboolean canvasEvent(GtkWidget *widget, GdkEvent *event,struct stateStruct *state); #define WIDTH 400 #define HEIGHT 300 #define INTERVAL 30 #define RADIUS 20 int main(int argc,char *argv[]) { GtkWidget *app; GtkWidget *canvas; struct stateStruct state; gnome_init("mousefollow","1.0",argc,argv); app = gnome_app_new("mousefollow", "Following Mouse Events"); gtk_signal_connect(GTK_OBJECT(app),"delete_event", GTK_SIGNAL_FUNC(eventDelete),NULL); gtk_signal_connect(GTK_OBJECT(app),"destroy", GTK_SIGNAL_FUNC(eventDestroy),NULL); canvas = gnome_canvas_new(); gtk_widget_set_usize(canvas,WIDTH,HEIGHT); gnome_app_set_contents(GNOME_APP(app),canvas); gtk_signal_connect(GTK_OBJECT(canvas),"event", GTK_SIGNAL_FUNC(canvasEvent),&state); gtk_widget_show_all(app); gtk_main(); exit(0); } gboolean canvasEvent(GtkWidget *widget, GdkEvent *event,struct stateStruct *state) { GdkColor color; GdkEventMotion *eventMotion; GdkEventCrossing *eventCrossing; GdkEventButton *eventButton; GdkEventExpose *eventExpose; static gint counter = 1; static GdkColormap *colormap; switch(event->type) { case GDK_MAP: g_print("%4d MAP\n",counter++); colormap = gdk_colormap_get_system(); state->lineGC = gdk_gc_new(widget->window); state->havePoints = FALSE; state->drawing = FALSE; break; case GDK_ENTER_NOTIFY: g_print("%4d ENTER_NOTIFY\n",counter++); eventCrossing = (GdkEventCrossing *)event; state->x = eventCrossing->x; state->y = eventCrossing->y; state->havePoints = TRUE; break; case GDK_LEAVE_NOTIFY: g_print("%4d LEAVE_NOTIFY\n",counter++); break; case GDK_BUTTON_PRESS: g_print("%4d BUTTON_PRESS\n",counter++); eventButton = (GdkEventButton *)event; if(eventButton->button == 1) { state->x = eventButton->x; state->y = eventButton->y; state->havePoints = TRUE; state->drawing = TRUE; } else if(eventButton->button == 3) { color.red=(((double)rand()*0xFFFF)/RAND_MAX); color.green=(((double)rand()*0xFFFF)/RAND_MAX); color.blue=(((double)rand()*0xFFFF)/RAND_MAX); gdk_color_alloc(colormap,&color); gdk_gc_set_foreground(state->lineGC,&color); } break; case GDK_BUTTON_RELEASE: g_print("%4d BUTTON_RELEASE\n",counter++); eventButton = (GdkEventButton *)event; if(eventButton->button == 1) { state->drawing = FALSE; state->havePoints = FALSE; } break; case GDK_2BUTTON_PRESS: g_print("%4d 2BUTTON_PRESS\n",counter++); eventButton = (GdkEventButton *)event; if(eventButton->button == 1) { gdk_draw_arc(eventButton->window,state->lineGC, TRUE, eventButton->x - RADIUS, eventButton->y - RADIUS, 2 * RADIUS,2 * RADIUS, 0,360*64); } break; case GDK_3BUTTON_PRESS: g_print("%4d 2BUTTON_PRESS\n",counter++); eventButton = (GdkEventButton *)event; if(eventButton->button == 2) exit(0); break; case GDK_MOTION_NOTIFY: g_print("%4d MOTION_NOTIFY\n",counter++); eventMotion = (GdkEventMotion *)event; if(state->havePoints && state->drawing) { gdk_draw_line(eventMotion->window, state->lineGC, state->x,state->y, (gint)(eventMotion->x), (gint)(eventMotion->y)); } state->x = (gint)(eventMotion->x); state->y = (gint)(eventMotion->y); state->havePoints = TRUE; break; case GDK_EXPOSE: eventExpose = (GdkEventExpose *)event; g_print("%4d EXPOSE\n",counter++); state->drawing = FALSE; state->havePoints = FALSE; gdk_window_clear(eventExpose->window); break; default: g_print("%4d Other: %d\n",counter++,event->type); break; } return(TRUE); } gint eventDelete(GtkWidget *widget, GdkEvent *event,gpointer data) { return(FALSE); } gint eventDestroy(GtkWidget *widget, GdkEvent *event,gpointer data) { gtk_main_quit(); return(0); }