#package Mup::EventLogger; package EventLogger; use Gtk2; # gtk+ has to be initialized before we can install the override, otherwise # it gets re-overridden. Glib::Idle->add (sub {Gtk2::Gdk::Event->handler_set (\&event_snooper)}, FALSE); sub setup { } sub teardown { } my %seen = (); my @ev = (); sub event_snooper { my $event = shift; my $type = $event->type; $seen{$type}++; $handler{$type}->($type, $event); Gtk2->main_do_event ($event); } my $seq = 'e0000000'; sub record { use Data::Dumper; #warn Dumper(\@_); my %e = ('type', @_); push @ev, \%e; print Data::Dumper->Dump ([\%e], [$seq++]); } # struct _GdkEventAny # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # }; # # struct _GdkEventExpose # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkRectangle area; # GdkRegion *region; # gint count; /* If non-zero, how many more events follow. */ # }; sub expose { my ($t, $e) = @_; # struct _GdkEventExpose record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; area => [ $e->area->values ], # GdkRectangle area; region => $e->region, # GdkRegion *region; count => $e->count, # gint count; ); } # # struct _GdkEventNoExpose # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # }; sub noexpose { my ($t, $e) = @_; # struct _GdkEventNoExpose record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; ); } # # struct _GdkEventVisibility # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkVisibilityState state; # }; sub visibility { my ($t, $e) = @_; # struct _GdkEventVisibilty record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; state => $e->state, # GdkVisibilityState state; ); } # # struct _GdkEventMotion # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # guint32 time; # gdouble x; # gdouble y; # gdouble *axes; # guint state; # gint16 is_hint; # GdkDevice *device; # gdouble x_root, y_root; # }; sub motion { my ($t, $e) = @_; # struct GdkEventMotion record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; time => $e->time, # guint32 time; x => $e->x, # gdouble x; y => $e->y, # gdouble y; #axes => $e->axes, # gdouble *axes; state => $e->state, # guint state; is_hint => $e->is_hint, # gint16 is_hint; #device => $e->device, # GdkDevice *device; x_root => $e->x_root, # gdouble x_root; y_root => $e->y_root, # gdouble y_root; ); } # # struct _GdkEventButton # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # guint32 time; # gdouble x; # gdouble y; # gdouble *axes; # guint state; # guint button; # GdkDevice *device; # gdouble x_root, y_root; # }; sub button { my ($t, $e) = @_; # struct GdkEventButton record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; time => $e->time, # guint32 time; x => $e->x, # gdouble x; y => $e->y, # gdouble y; #axes => $e->axes, # gdouble *axes; state => $e->state, # guint state; button => $e->button, # guint button; #device => $e->device, # GdkDevice *device; x_root => $e->x_root, # gdouble x_root; y_root => $e->y_root, # gdouble y_root; ); } # # struct _GdkEventScroll # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # guint32 time; # gdouble x; # gdouble y; # guint state; # GdkScrollDirection direction; # GdkDevice *device; # gdouble x_root, y_root; # }; sub scroll { my ($t, $e) = @_; # struct GdkEventScroll record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; time => $e->time, # guint32 time; x => $e->x, # gdouble x; y => $e->y, # gdouble y; state => $e->state, # guint state; direction => $e->direction, # GdkScrollDirection direction; #device => $e->device, # GdkDevice *device; x_root => $e->x_root, # gdouble x_root; y_root => $e->y_root, # gdouble y_root; ); } # # struct _GdkEventKey # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # guint32 time; # guint state; # guint keyval; # gint length; # gchar *string; # guint16 hardware_keycode; # guint8 group; # }; sub key { my ($t, $e) = @_; # struct GdkEventKey record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; time => $e->time, # guint32 time; state => $e->state, # guint state; keyval => $e->keyval, # guint keyval; #length => $e->length, # gint length; #string => $e->string, # gchar *string; hardware_keycode => $e->hardware_keycode, # guint16 hardware_keycode; group => $e->group, # guint8 group; ); } # # struct _GdkEventCrossing # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkWindow *subwindow; # guint32 time; # gdouble x; # gdouble y; # gdouble x_root; # gdouble y_root; # GdkCrossingMode mode; # GdkNotifyType detail; # gboolean focus; # guint state; # }; sub crossing { my ($t, $e) = @_; # struct GdkEventCrossing record ($t, # GdkEventType type; window => $e->window, # GdkWindow *window; send_event => $e->send_event, # gint8 send_event; subwindow => $e->subwindow, # GdkWindow *subwindow time => $e->time, # guint32 time; x => $e->x, # gdouble x; y => $e->y, # gdouble y; x_root => $e->x_root, # gdouble x_root; y_root => $e->y_root, # gdouble y_root; mode => $e->mode, # GdkCrossingMode mode; detail => $e->detail, # GdkNotifyType detail; focus => $e->focus, # gboolean focus; state => $e->state, # guint state; ); } # # struct _GdkEventFocus # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # gint16 in; # }; # # struct _GdkEventConfigure # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # gint x, y; # gint width; # gint height; # }; # # struct _GdkEventProperty # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkAtom atom; # guint32 time; # guint state; # }; # # struct _GdkEventSelection # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkAtom selection; # GdkAtom target; # GdkAtom property; # guint32 time; # GdkNativeWindow requestor; # }; # # /* This event type will be used pretty rarely. It only is important # for XInput aware programs that are drawing their own cursor */ # # struct _GdkEventProximity # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # guint32 time; # GdkDevice *device; # }; # # struct _GdkEventClient # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkAtom message_type; # gushort data_format; # union { # char b[20]; # short s[10]; # long l[5]; # } data; # }; # # struct _GdkEventSetting # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkSettingAction action; # char *name; # }; # # struct _GdkEventWindowState # { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkWindowState changed_mask; # GdkWindowState new_window_state; # }; # # /* Event types for DND */ # # struct _GdkEventDND { # GdkEventType type; # GdkWindow *window; # gint8 send_event; # GdkDragContext *context; # # guint32 time; # gshort x_root, y_root; # }; sub _default { my ($t, $e) = @_; record ($t, ev => $e, time => $e->time); } our %handler = ( 'nothing' => \&_default, 'delete' => \&_default, 'destroy' => \&_default, 'expose' => \&expose, 'motion-notify' => \&motion, 'button-press' => \&button, '2button-press' => \&button, '3button-press' => \&button, 'button-release' => \&button, 'key-press' => \&key, 'key-release' => \&key, 'enter-notify' => \&crossing, 'leave-notify' => \&crossing, 'focus-change' => \&_default, 'configure' => \&_default, 'map' => \&_default, 'unmap' => \&_default, 'property-notify' => \&_default, 'selection-clear' => \&_default, 'selection-request' => \&_default, 'selection-notify' => \&_default, 'proximity-in' => \&_default, 'proximity-out' => \&_default, 'drag-enter' => \&_default, 'drag-leave' => \&_default, 'drag-motion' => \&_default, 'drag-status' => \&_default, 'drop-start' => \&_default, 'drop-finished' => \&_default, 'client-event' => \&_default, 'visibility-notify' => \&_default, 'no-expose' => \&_default, 'scroll' => \&scroll, 'window-state' => \&_default, 'setting' => \&_default, ); END { #use Data::Dumper; print map{ "$seen{$_}\t$_\n" } sort {$seen{$a} <=> $seen{$b}} keys %seen; #print Dumper(\@ev); } 1;