Блокируем клавиатуру в Linux

Изначально может показаться, что это очень странная задача, ведь можно просто заблокировать экран. Но если у вас в доме появился маленький ребенок, который то и дело норовит что то нажать, то поговорить, например, по Skype становится нереально. Итак, нужно максимально быстро заблокировать/разблокировать клавиатуру, чтобы маленький человечек не мог нажать/закрыть/удалить что-то во время общения по Skype с родственниками.

baby

Сначала Гугл меня навел меня на мысль использовать для этих целей xinput, но по какой то неведомомй причине моя клавиатура упорно не блокировалась. Дальнейшие поиски решения привели проекту Lock Keyboard for Baby. Проект не развивается уже с 2008, но у меня все заработало «с пол пинка». Итак, скачиваем скрипт и кладем его в папочку /usr/bin:

sudo mv lock-keyboard-for-baby-20080706.pl /usr/bin/lock
sudo chmod +x /usr/bin/lock

Откройте скрипт в любом удобном редакторе в первой строке поменяйте путь до вашего интерпретатора perl. Подсмотеть где он располагается можно используя команду

which perl

Далее в 7 строке (параметр defaultpassword) задайте пароль для разблокировки. После чего сохраните изменения и попробуйте его запустить. Если клавиатура заблокировалась, то все в порядке и блокировку можно вызывать по комбинации клавишь Alf+F2 и введя команду lock.

Под катом итоговый скрипт. Спасибо за внимание.

#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
my $lastmod="2006/05/25";
my $datemod="2008/07/03";
my $defaultpassword="lock";
my $progname=$0;
$progname =~ s%.*/%%g;

sub usage($)
{
my ($exitcode)[email protected]_;

print STDERR <<end_of_usage ;="" usage="" for="" $progname="" [-xy="XX,YY]" [-p|password="" thepassword]="" [-stars|-visible|-visible="maxlen]" [-message]="" [-w|-withmouse]="" [-help]="" was="" written="" by:chris="" sincock="" (this="" version="" $datemod)="" copyright="" (c)="" 2006="" chris="" '-withmouse'="" option="" added="" 2008="" andrew="" oakley="" under="" gpl="" this="" is="" free="" software;="" see="" the="" gnu="" license="" copying="" conditions.="" there="" no="" warranty;="" not="" even="" merchantability="" or="" fitness="" a="" particular="" purpose="" if="" you="" specify="" -password="" -stars="" it="" will="" default="" to="" telling="" what="" password="" type="" don't="" -vis,="" tell="" and="" be="" $defaultpassword="" 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=$true;
my $withmouse=$false;
my $maxshownlength=30;
my $defaults_changed=$false;
my $defaults_changed_vis=$false;

my @startpos=(0,0);

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([email protected])
{
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([email protected])
{
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()
{
$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()
{
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)[email protected]_;
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(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', \&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;
Рекомендуем почитать
Быстрый тест работы smtp сервера, включая проверку DKIM и SPF

Наверное, все системные администраторы, которые отвечают за доставку электронной почты, что для успешной доставки писем с домена вашей организации является Читать дальше...

Пишем логи IIS в MSSQL

Цель: организовать хранилище логов IIS под управлением MSSQL. Условия: Для удобного поиска (SELECT'а) по времени значение date и time должны Читать дальше...

Экстракт на все времена

Название конечно шуточное, но намекающее на то, о чем хочу написать. А написать я хотел на тему распаковывания файлов разных Читать дальше...

Обзор PAC Manager под Linux

В который раз я убеждаюсь в "силе" OpenSource. Не в той силе, что OpenSource-программы на много круче закрытых аналогов, а Читать дальше...

Поделиться

Оставить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *