Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:
Hello There.
I am trying to modify muppet's excellent scribble.pl program (a simple drawing program using Gtk2) to detect which input (touchpad/pen/eraser) generates mouse event. Ultimately, I would like to draw differents things depending on whether I use a touchpad or a stylus.
My understanding is that I need to activate the inputs generating the "extended events", as well as indicate that I want to receive such extended events.
I've attached my code at the end of this message. Besides adding debug lines to print out which input is generating events, I've only added the following lines:
my $display=$vbox->get_display; my @list=($display->list_devices()); for(my $i=0;$i<$#list;$i++){ my $name=$list[$i]->name; my $result=$list[$i]->set_mode('GDK_MODE_SCREEN'); print "activating device \# $i, name=$name result=$result\n"; } $drawing_area->set_extension_events("cursor");
The first few lines take care of the activation of the inputs (and seem to work well). However, using the last line above results in segfault when issuing $window->show;.
Note that I have a C code scribble-xinput.c that works fine and has the same structure (at least from what I gather), so I know it should work somehow, but I can't figure it out.
Any help greatly appreciated.
#!/usr/bin/perl -w # use strict; use Glib qw/TRUE FALSE/; use Gtk2; my $pixmap = undef; sub configure_event { my $widget = shift; # GtkWidget *widget my $event = shift; # GdkEventConfigure *event $pixmap = Gtk2::Gdk::Pixmap->new ($widget->window,$widget->allocation- +>width,$widget->allocation->height,-1); $pixmap->draw_rectangle ($widget->style->white_gc,TRUE,0, 0,$widget->a +llocation->width,$widget->allocation->height); return TRUE; } sub expose_event { my $widget = shift; # GtkWidget *widget my $event = shift; # GdkEventExpose *event $widget->window->draw_drawable ($widget->style->fg_gc($widget->state), +$pixmap,$event->area->x, $event->area->y, $event->area->x, $event->area->y,$event->area->width, $event->area->he +ight); return FALSE; } sub draw_brush { my ($widget, $x, $y) = @_; # this is not a real GdkRectangle structure; we don't actually need on +e. my @update_rect; $update_rect[0] = $x - 5; $update_rect[1] = $y - 5; $update_rect[2] = 10; $update_rect[3] = 10; $pixmap->draw_rectangle ($widget->style->black_gc, TRUE, @update_rect); $widget->queue_draw_area (@update_rect); } sub button_press_event { my $widget = shift; # GtkWidget *widget my $event = shift; # GdkEventButton *event if ($event->button == 1 && defined $pixmap) { draw_brush ($widget, $event->coords); my @lala=$event->coords; my $device=$event->device; my $name=$device->name; my $source=$device->source; print "$lala[0] $lala[1] from press $name $source\n"; } if ($event->button == 3 && defined $pixmap) { my @lala=$event->coords; my $device=$event->device; my $name=$device->name; my $source=$device->source; print "$lala[0] $lala[1] from press $name $source\n"; } return TRUE; } sub motion_notify_event { my $widget = shift; # GtkWidget *widget my $event = shift; # GdkEventMotion *event my ($x, $y, $state); if ($event->is_hint) { (undef, $x, $y, $state) = $event->window->get_pointer; } else { $x = $event->x; $y = $event->y; $state = $event->state; } if ($state >= "button1-mask" && defined $pixmap) { draw_brush ($widget, $x, $y); print "$x,$y from motion\n"; my @lala=$event->coords; my $device=$event->device; my $name=$device->name; my $source=$device->source; print "$lala[0] $lala[1] from motion $name $source\n"; } return TRUE; } { Gtk2->init; my $window = Gtk2::Window->new ('toplevel'); $window->set_name ("Test Input"); my $vbox = Gtk2::VBox->new (FALSE, 0); $window->add ($vbox); $vbox->show; $window->signal_connect ("destroy", sub { exit(0); }); # Create the drawing area my $drawing_area = Gtk2::DrawingArea->new; $drawing_area->set_size_request (200, 200); $vbox->pack_start ($drawing_area, TRUE, TRUE, 0); $drawing_area->show; # Signals used to handle backing pixmap $drawing_area->signal_connect (expose_event => \&expose_event); $drawing_area->signal_connect (configure_event => \&configure_event); # Event signals $drawing_area->signal_connect (motion_notify_event => \&motion_notify_ +event); $drawing_area->signal_connect (button_press_event => \&button_press_ev +ent); $drawing_area->set_events ([qw/ exposure-mask leave-notify-mask button-press-mask pointer-motion-mask pointer-motion-hint-mask/]); my $display=$vbox->get_display; my @list=($display->list_devices()); for(my $i=0;$i<$#list;$i++){ my $name=$list[$i]->name; my $result=$list[$i]->set_mode('GDK_MODE_SCREEN'); print "activating device \# $i, name=$name result=$result\n"; } $drawing_area->set_extension_events("cursor"); # .. And a quit button my $button = Gtk2::Button->new ("Quit"); $vbox->pack_start ($button, FALSE, FALSE, 0); $button->signal_connect_swapped (clicked => sub { $_[0]->destroy; }, $ +window); $button->show; $window->show; Gtk2->main; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: segfault using extension events in Gtk2's scribble.pl
by gvb (Novice) on Dec 03, 2014 at 13:30 UTC |