• # Solution adoptée ?

    Posté par . En réponse au message Photomaton lors d'un mariage. Évalué à 10. Dernière modification le 29 mars 2011 à 19:47.

    Bonjour,

    Alors finalement, je suis parti d'un script perl de Chris Sincock et l'ai adapté pour mon usage.
    Le script initial est dispo ici :
    http://sourceforge.net/projects/lk4b/files/lk4b/

    Il permet de capturer tous les événements du clavier et ne débloque qu'à la saisie d'un mot de passe.

    J'ai ajouté :

    • l'utilisation d'xmodmap afin de désactiver les touches 'Ctrl' (pour éviter que l'utilisateur ne puisse appeler Ctrl+Alt+F1 par exemple)
    • l'utilisation d'xdotool (http://www.semicomplete.com/projects/xdotool/) pour transmettre la touche Espace à Cheese afin de provoquer la prise de la photo

    D'ailleurs, dans mes recherches, j'ai également découvert l'application xdrtool qui permet aussi de bloquer clavier et souris jusqu'à saisie d'un mot de passe.

    Et voici le code en l'état actuel :

    #!/bin/env perl
    use warnings;
    use strict;
    use Data::Dumper;
    my $lastmod="2006/05/25";
    my $datemod="2011/03/29";
    my $defaultpassword="mypassword";
    my $progname=0ドル;
    $progname =~ s%.*/%%g;
    sub usage($)
    {
     my ($exitcode)=@_;
     print STDERR <<END_OF_USAGE ;
    usage for $progname
    $progname [-xy=XX,YY]
    			 [-p|password thepassword]
    			 [-stars|-visible|-visible=maxlen]
    			 [-message]
    			 [-w|-withmouse]
    			 [-help]
    $progname was written by:Chris Sincock
    (this version $datemod)
    Copyright (C) 2006 Chris Sincock
     -withmouse option added 2008 Andrew Oakley under GPL
     adapted by PAB to work with cheese to do a photobooth !
    This is free software; see the GNU GPL license for copying conditions.
    There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR
    A PARTICULAR PURPOSE
    If you specify -password or -stars it will default to not telling you
     what password to type
    If you do not specify -password or -stars or -vis, it will tell you
     what password to type and the password will be $defaultpassword
    You can clear whatever has already been typed by hitting <Return>
    END_OF_USAGE
     exit($exitcode);
    }
    my $password=$defaultpassword;
    my $message="Type the password to quit\n:";
    my $true=1;
    my $false=0;
    my $noshow=$false;
    my $withmouse=$false;
    my $maxshownlength=30;
    my $defaults_changed=$false;
    my $defaults_changed_vis=$false;
    my @startpos=(50,50);
    while (@ARGV)
    {
     my $arg=shift @ARGV;
     if($arg =~ /^-xy=(\d+),(\d+)$/i)
     {
     @startpos=(1ドル,2ドル);
     }
     elsif($arg =~ /^(-|--)(h|help|usage|[?])$/i)
     {
     usage(0);
     }
     elsif($arg =~ /^(-|--)(p|pass|password)$/i)
     {
     if(!@ARGV)
     {
     print STDERR "missing argument\n";
     usage(-1);
     }
     $password=shift @ARGV;
     $defaults_changed=$true;
     }
     elsif($arg =~ /^(-|--)(s|stars)$/i)
     {
     $noshow="stars";
     $defaults_changed=$true;
     }
     elsif($arg =~ /^(-|--)(w|withmouse)$/i)
     {
     $withmouse=$true;
     $defaults_changed=$true;
     $defaults_changed_vis=$true;
     }
     elsif($arg =~ /^(-|--)(v|vis|visible)(=(\d+)|)$/i)
     {
     $noshow=$false;
     if(length(4ドル))
     {
     $maxshownlength=4ドル;
     }
     $defaults_changed=$true;
     $defaults_changed_vis=$true;
     }
     elsif($arg =~ /^(-|--)(m|msg|message)$/i)
     {
     if(!@ARGV)
     {
     print STDERR "missing argument\n";
     usage(-1);
     }
     $message=shift @ARGV;
     if(length($message))
     {
     $message.="\n";
     }
     $defaults_changed=$true;
     }
     else
     {
     usage(-1);
     }
    }
    if(!$defaults_changed)
    {
     $noshow=$false;
    }
    if((!$defaults_changed || $defaults_changed_vis))
    {
     $message="Type password to quit\n";
    }
    use Gtk2 -init;
    my $w = new Gtk2::Window -popup;
    my $l = new Gtk2::Label $message;
    my $eb = new Gtk2::EventBox;
    my $gdkwin;
    my $grabstatus;
    my $typed="";
    sub do_grab()
    {
     system "xdotool search --onlyvisible --classname 'Cheese' windowactivate --sync key F11";
     system "xmodmap -e 'keycode 37 = ' ";
     system "xmodmap -e 'keycode 105 = ' ";
     $grabstatus= Gtk2::Gdk->keyboard_grab(
     $gdkwin,$true,Gtk2::Gdk::X11->get_server_time($gdkwin) );
     if($grabstatus ne "success")
     {
     $l->set_text("keyboard grab failed");
     }
     if($withmouse)
     {
     $grabstatus= Gtk2::Gdk->pointer_grab(
     $gdkwin,$true,['button-press-mask','button-release-mask'],undef,undef,Gtk2::Gdk::X11->get_server_time($gdkwin));
     if($grabstatus ne "success")
     {
     $l->set_text("pointer grab failed");
     }
     }
    }
    sub do_ungrab()
    {
     system "xmodmap -e 'keycode 37 = Control_L NoSymbol Control_L'";
     system "xmodmap -e 'keycode 105 = Control_R NoSymbol Control_R'";
     Gtk2::Gdk->keyboard_ungrab(Gtk2::Gdk::X11->get_server_time($gdkwin));
     if($withmouse)
     {
     Gtk2::Gdk->pointer_ungrab(Gtk2::Gdk::X11->get_server_time($gdkwin));
     }
    }
    sub do_keypress(@)
    {
     my ($widg,$evt)=@_;
     my $kv = $evt->keyval;
     my $cs = Gtk2::Gdk->keyval_name($kv);
     if($cs =~ /Return|Enter/)
     {
     if($typed eq $password)
     {
     do_ungrab();
     Gtk2->main_quit;
     }
     else
     {
     $typed="";
     }
     }
     elsif($cs =~ /space/)
     {
     system "xdotool search --onlyvisible --classname 'Cheese' windowactivate --sync key space";
     }
     elsif(length($cs) == 1 && $cs =~ /[[:print:]]/)
     {
     $typed .= $cs;
     }
     my $showtyped=$typed;
     if($noshow eq "stars")
     {
     $showtyped =~ s/[^*]/*/g;
     }
     elsif($noshow)
     {
     $showtyped="";
     }
     if(length($showtyped) > $maxshownlength)
     {
     $showtyped=substr($showtyped,0,$maxshownlength);
     }
     $l->set_text($message.$showtyped);
    }
    $w->add($eb);
    $eb->add($l);
    $w->add_events( [ qw(key_press_mask) ]);
    $w->signal_connect('key_press_event', 669cc01ce3a2f62b9ad1e9ea2aeb4789562db6a2amp;do_keypress);
    $w->signal_connect('realize', sub { $w->window->move(@startpos); });
    $w->signal_connect('map', sub { $gdkwin=$w->window; do_grab(); });
    $w->show_all;
    Gtk2->main;