Создание эффектных экранных сообщений при помощи Ghosd и Perl (исходники)

Натан Харингтон, программист, IBM

Программный код и подходы, описываемые в данной статье, - это только пример возможной реализации экранных сообщений. Они рассчитаны на машину, работающую в закрытой сети, и не подходят для машины, имеющей незащищенное соединение с Интернетом, поскольку при этом посторонние вредоносные программы смогут исполнять на машине произвольный неконтролируемый код.

Выводимые на экран сообщения для графического представления рабочего стола в Windows и Linux существуют уже много лет. Недавно появившиеся безрамочные прозрачные окна для рабочего стола Linux открыли графические возможности нового уровня. Среда Ghosd позволяет создавать экранные сообщения нового поколения - со сглаженными шрифтами, цветовой гаммой True Color, тенями, прозрачностью и возможностью загрузки изображений из файлов.

Используя Perl и некоторые специально скомпилированные программы Ghosd, я покажу вам, как создать свою собственную систему уведомлений о событиях. С помощью простых правил сопоставления с ключевыми словами и клиент-серверной конфигурации вы сможете получать экранные уведомления со всех ваших систем, как удаленных, так и локальных..

Требования

Аппаратное обеспечение

Мощности любого ПК, произведенного позже 2000 года, с большим запасом хватит для компилирования и выполнения программного кода. Если у вас есть графический рабочий стол, у вас скорее всего уже имеется процессор достаточной мощности.

Программное обеспечение

Программа Ghosd требует наличия библиотек Pango и Cairo. При компиляции и конфигурировании Ghosd эти библиотеки уже должны быть установлены. Обратитесь к разделу Ресурсы, где имеются ссылки на библиотеки Cairo и Pango, или сделайте еще один шаг вперед и установите какой-либо дистрибутив Linux, в котором эти библиотеки уже имеются. Я рекомендую Vector Linux, поскольку в нем уже предустановлены и настроены все библиотеки и визуальные эффекты, так что вы можете заняться непосредственно Ghosd.

После установки Pango и Cairo необходимо скомпилировать саму программу Ghosd. Загрузите и распакуйте архив, содержащий исходный код Ghosd. Затем скомпилируйте его с помощью команды ./configure && make install. По завершении процессов установки и настройки ознакомьтесь с некоторыми вариантами использования Ghosd, перейдя в каталог примеров программ. Ghosd частично написан как библиотека функций, помогающая вашим приложениям использовать метафору разработки экранных изображений. По сути, приведенные примеры - это небольшие программы на языке C, иллюстрирующие не только то, как использовать Ghosd из командной строки, но и то, как интегрировать его в ваши программы.

Написание утилит командной строки для экранного вывода

Модификация text.c для использования в командной строке

Откройте каталог примеров программ и запустите программу text.c посредством команды ./text. В нижнем правом углу экрана вы увидите закодированный в программе текст белого цвета. Для наших целей мы хотели бы иметь возможность задавать цвет, положение и содержание текстового сообщения. Вместо того чтобы создавать новую программу, изменим существующую программу text.c в соответствии с нашими требованиями. Если вы хотите пропустить этот шаг, загрузите готовый файл text.c, включенный в архив исходного кода, и скомпилируйте его с помощью команды make.

Добавьте приведенные ниже переменные в раздел объявлений переменных.

Листинг 1. Обновленный раздел объявлений test.c

                
int   posX   = -50;
int   posY   = -50;
float red    = 1.0;
float green  = 1.0;
float blue   = 1.0;
int   ftSize = 30;
int   fadIn  = 300;
int   fadOut = 1500;
char  displayText[500] = "default message";

Это переменные по умолчанию для задания положения, содержания текста, цвета и размера шрифта, скорости появления и исчезновения изображения в миллисекундах, а также массива для хранения отображаемой строки. Теперь необходимо изменить отображаемый фрагмент текста с учетом указанного цвета. В функции визуализации (render) измените строку cairo_set_source_rgba(cr, 1, 1, 1, 1.0); на cairo_set_source_rgba(cr, red, green, blue, 1.0);. Это позволит вам использовать значения цветов, передаваемые через параметры командной строки.

Необходимо также изменить программу, чтобы она выводила сообщение по умолчанию, а не давала сбой, если в командной строке заданы не все параметры. В функции main удалите строки, приведенные ниже.

Листинг 2. Закодированное в main() экранное сообщение

                
  pango_layout_set_markup(layout,
                          "<span font_desc='Trebuchet 30'>"
                          "some sample text using <b>ghosd</b>"
                          /* "ار�~Jد" */
                          "</span>", -1);
  ghosd = ghosd_new();
  ghosd_text_set_position(ghosd, -50, -50, layout);
  ghosd_set_render(ghosd, render, layout);

  ghosd_flash(ghosd, 300, 1500);
  

После удаления указанного выше кода введите код проверки на ошибку и вывода сообщения по умолчанию, приведенный ниже.

Листинг 3. Проверка на ошибку и вывод сообщения по умолчанию с помощью main()

                
  if( argc == 10 )
  { 
    posX   = atoi(argv[2]);
    posY   = atoi(argv[3]);
    red    = atoi(argv[4]);
    green  = atoi(argv[5]);
    blue   = atoi(argv[6]);
    ftSize = atoi(argv[7]);
    fadIn  = atoi(argv[8]);
    fadOt  = atoi(argv[9]);
    sprintf(displayText, "<span font_desc='Trebuchet %d'>%s</span>", ftSize, argv[1]);
  }else{
    sprintf(displayText,"<span font_desc='Trebuchet 30'>Incomplete command</span>");
  }
  pango_layout_set_markup(layout, displayText, -1 );
  ghosd = ghosd_new();
  ghosd_text_set_position(ghosd, posX, posY, layout);
  ghosd_set_render(ghosd, render, layout);
  ghosd_flash(ghosd, fadIn, fadOt);

Теперь, когда мы ввели простой код проверки ошибок и модифицировали формат Pango, текст будет выводиться так, как указано в командной строке, с заданным размером и цветом шрифта и параметрами изменения яркости. Создайте новую исполняемую программу вывода текста с помощью команды make. Запустите программу вывода текста для Ghosd командой типа ./text "red text example" -150 -150 1.0 0.1 0.1 40 500 2000. Приведенная командная строка выведет текст "red text example" красным шрифтом размером 40pt в точке с экранными координатами -150,-150. В течение 500 миллисекунд яркость будет увеличиваться, а затем в течение 2000 миллисекунд снижаться до нуля.

В каталоге примеров программ имеется пример вывода на экран изображения, прекрасно подходящий для наших целей. Введите команду ./image /usr/share/pixmaps/x264.png -x 40 -y 40 для вывода на экран простого изображения. Приведенный ниже рисунок иллюстрирует одновременный вывод текста и графического изображения.

Рисунок 1. Пример вывода текста и изображения в Ghosd
Пример вывода текста и изображения в Ghosd 

Вывод экранных уведомлений с использованием Perl и Ghosd

Общая стратегия: клиент-серверный подход

Программа Ghosd позволяет выводить на экран текст и изображения с любыми вариациями размера, цвета и стиля. Чтобы эффективно использовать эти возможности для слежения за сообщениями о состоянии системы, сообщениями электронной почты и любыми другими параметрами, необходимо сохранить эту гибкость и при этом предоставить простой интерфейс для ее использования. Система, представленная ниже, использует клиент-серверную архитектуру для приема от локальных и удаленных машин событий, сообщение о которых необходимо вывести на экран.

Строка сообщения, отправленная клиентом, обрабатывается на предмет наличия заданных ключевых слов (считываемых из файла конфигурации), и соответствующие данные выводятся на экран. Так, если сервер получает строку New e-mail from mark@developerWorks, он находит ключевое слово e-mail и выведет изображение, соответствующее почтовому сообщению, а также полный текст сообщения в нижнем правом углу монитора. Если строка сообщения, отправленная клиентом, содержит слово "error" (ошибка), строка сообщения будет выведена полностью крупными красными буквами по центру экрана.

Приступим к программной реализации, чтобы посмотреть, как все это работает на практике.

Реализация на сервере

Сервер должен считывать файл конфигурации, чтобы определить, как отображать текст и изображения. Он также должен исполнять бесконечный цикл для прослушивания подключений клиентов к указанному порту. После установления соединения - с локальной или удаленной машиной - входящие сообщения обрабатываются на предмет наличия ключевых слов, указанных в файле конфигурации. Текст или изображение выводятся на экран в соответствии с параметрами в файле конфигурации. Закончив на этом обзор работы программы, перейдём к разделу объявлений переменных.

Листинг 4. Объявление osdServer.pl

                
#!/usr/bin/perl -w
# osdServer.pl - process incoming text events based on keyword matching and
#                display using Ghosd
use strict;
use FileHandle;
use Socket;

if( @ARGV != 1 ){ die "specify a port to listen on " }
my %osdHash = ();
my $proto    = "";
my $port     = "";
my $sockAddr = "";
my $fullCmd  = "";

Далее следуют подпрограммы, начиная с readOsdFile, которая считывает файл osdServer.config и считывает из него требуемые ключевые слова и параметры вывода сообщения.

Листинг 4. Подпрограмма readOsdFile

                
# readKeyWordFile reads type, keywords, (text/image) parameters
# text parameters:
# X coordinate, Y coordinate, red, green, blue, font size, fade In, fade Out
# image parameters:
# image filename, X coordinate, Y coordinate
# osdServer.confg format is:  type _#_ keywords _#_ osd parameters
sub readOsdFile  
{ 
  open(OSDFILE,"osdServer.config") or die "no osdServer.config file: $!";
    while(<OSDFILE>){
      # ignore comment lines
      if( !/^#/ ){
        chomp($_);
        my @arrLine = split "_#_";
        $arrLine[0] =~ s/ //g;
        $osdHash{ lc($arrLine[0]) }{ $arrLine[1] } = $arrLine[2];
      }#if not a comment line
    }#for each line in file
  close(OSDFILE);
}#readOsdFile

После задания параметров поиска ключевых слов и вывода изображения мы можем перейти к простой подпрограмме сопоставления с ключевыми словами matchWords.

Листинг 5. Подпрограмма matchWords

                
sub matchWords
{ 
  my $msgString = $_[0];
  my $type      = $_[1];

  # for the type specified
  for my $kwList ( keys %{ $osdHash{$type} } )
  { 
    # for each word
    for my $checkWord ( split " ", $kwList )
    { 
      $checkWord =~ s/ //g;
      if( $msgString =~ /$checkWord/i )
      { 
        if( $type eq "text" )
        { 
          $fullCmd .= qq{./text '$msgString' $osdHash{text}{$kwList} &};
        }else
        { 
          $fullCmd .= qq{./image -i $osdHash{image}{$kwList} &};
        }
      }#if matching word
    }#for each check word
  }#for each key word list

}#checkText

Подпрограмма matchWords производит простую проверку на наличие слов, указанных в файле osdServer.config, а затем формирует команду для вывода информации в зависимости от типа отображаемого сообщения. Например, она сформирует команду Ghosd для вывода изображения, если имеется соответствующее ключевое слово и в файле конфигурации задано изображение для вывода на экран. Задав подпрограммы, мы быстро переходим к рассмотрению логики короткой главной программы.

Листинг 6. Логика главной программы для osdServer.pl

                
readOsdFile();

$proto = getprotobyname('tcp');
socket(SERVER, PF_INET, SOCK_STREAM, $proto) or die "socket: $!\n";

$port     = $ARGV[0];
$sockAddr = sockaddr_in($port, INADDR_ANY);
bind(SERVER, $sockAddr) or die "bind: $!\n";

listen(SERVER, SOMAXCONN) or die "listen: $!\n";

# listen forever
while( 1 )
{
  my $acceptSock = accept(HANDLER, SERVER) or die "accept: $!\n";
  my($acceptPort, $acceptIpAddr) = sockaddr_in($acceptSock);

  autoflush HANDLER 1;
  while(my $msgString = <HANDLER>)
  {
    chomp($msgString);

    matchWords($msgString,"text");
    matchWords($msgString,"image");

    $fullCmd = `$fullCmd` unless $fullCmd eq "";
    $fullCmd = "";
  }#while handler

  close HANDLER or die "close HANDLER: $!\n";

}#while forever

Первая часть логики главной программы вызывает readOsdFile для задания сопоставления ключевых слов и параметров хешей(hash). После стандартного кода прослушивания сокета запускается основной цикл, прослушивающий новые соединения. Каждый раз при новом соединении выполняется проверка на совпадение со всеми ключевыми словами текста и изображения, указанными в файле конфигурации. При каждом обнаружении совпадения к полной команде приписывается соответствующий текст; полная команда для отображаемого события исполняется вся целиком. При таком подходе заданные для одного события совмещенные отображения (графика плюс текст), например, текстовое сообщение и изображение при получении электронной почты, выводятся на экран строго одновременно.

Файл конфигурации

Теперь, когда серверный код готов, можно приступить к созданию собственного файла конфигурации для отображения текста в таком виде, как вам этого хочется. В качестве стартовой точки ниже приведен пример файла конфигурации:

Листинг 7. Пример файла osdServer.config

                
text _#_ email _#_ -250 -250 0.1 0.1 1.0 20 100 4300
text _#_ SYS _#_ -150 -150 0.1 1.0 0.1 30 100 4300
image _#_ SYS _#_ /usr/share/pixmaps/taskmanager.png -x -510 -y -510

Напомним, что формат файла osdServer.config - type _#_ keyword _#_ ghosd parameters, где параметры определены типом, указанным в первом поле. Например, в первой строке указано, что если во входной строке где-либо присутствует слово "email", надо вывести сообщение красным шрифтом размером 20 пунктов в позиции с координатами -250,-250, наращивая яркость в течение 100 мс и затем снижая ее до нуля спустя четыре секунды с небольшим. Строка изображения указывает рисунок и координаты его размещения на экране, а также сдержит ключевое слово "SYS." Мы коснемся его чуть позже, при рассмотрении примера использования программы для слежения за файлами журнала.

Реализация клиента

Листинг 8. Реализация osdClient.pl

                
#!/usr/bin/perl -w
# osdClient.pl - send simple client text to server
use strict;
use IO::Socket::INET;
use POSIX qw(F_GETFL F_SETFL O_NONBLOCK);
my $sock = "";

if( $#ARGV != 2 ){ die "specify a ip, port, text string" }

eval
{
  $sock = IO::Socket::INET->new( 
    PeerAddr => $ARGV[0],
    PeerPort => $ARGV[1]) // die "can't set it up $!";

  $sock->blocking(0)
};

if( $@ =~ /socket/i )
{
  die "die in record retrieval socket setup with $@";
}

print $sock "$ARGV[2] \n";

Этот простой фрагмент программного кода устанавливает соединение с указанным сервером через указанный порт и затем отправляет переданный ему в командной строке текст серверу. Существует множество прекрасных публикаций и руководств, содержащих подробное описание сетевых возможностей Perl.

При написании этих скриптов (или загрузке их из архива исходного кода), проследите, чтобы они были размещены в том же каталоге, что и примеры программ Ghosd; обычно это каталог ghosd-0.0.1/examples.

Примеры реализации и уведомления

Запустите программу osdServer.pl с помощью команды perl osdServer.pl 9090. Серверная программа теперь будет постоянно слушать порт 9090, пытаясь обнаружить TCP-подключения от любого хоста. Допустим, вы использовали пример конфигурации, приведенный выше. Вы можете опробовать построенную систему вывода на экран, введя команду perl osdClient.pl 127.0.0.1 9090 "email test". Результатом ее выполнения будет вывод на экран текстового сообщения "email test" синим шрифтом.

Теперь вы готовы двигаться вперед! Ниже приведено несколько более сложных примеров, чтобы помочь вам освоиться.

Пример сообщения xmms

Для отображения названия проигрываемой в настоящий момент песни при каждой смене трека в xmms следуйте приведенным далее инструкциям. Перейдите в диалоговое окно Preferences в xmms, нажав Ctrl+P. Выберите вкладку general plug-ins и включите опцию Song Change plug-in. Нажмите configure (настроить) и добавьте следующую строку:

/usr/bin/perl (fullpathTo_osdClient.pl) 127.0.0.1 9090 "%n xmms"

В результате название текущей песни будет автоматически передаваться программе osdServer.pl через клиент. Для правильного распознавания событий xmms необходимо добавить в файл osdServer.config следующую строку:

text _#_ xmms _#_ -150 -150 1.0 1.0 0.1 20 500 2300

Пример уведомления системного журнала

Ниже приведена короткая программа, которая контролирует ваш системный журнал на предмет появления любых событий, и отправляет уведомления программе osdServer.pl:

tail -n0 -f /var/log/messages /  perl -lane '$_=substr($_,30,50);$r=`perl osdClient.pl 127.0.0.1 9090 "$_ SYS"`'

Строка tail -n0 -f сообщает о том, что нужно перейти в конец файла и ждать новых изменений. Затем наша короткая программа передает строку программе osdServer.pl при помощи программы osdClient.pl, эта строка состоит из первых 50 значимых байтов записи в файле журнала. Ключевое слово "SYS", которое уже встречалось в примере файла osdServer.config, необходимо, чтобы разрешить выполнение проверки на ключевые слова для всех системных сообщений, независимо от их конкретного содержания.

Заключение и дополнительные примеры

Из двух последних, более сложных, примеров, вы должны были понять, как интегрировать сервер и клиент экранных сообщений Ghosd в вашу вычислительную среду. Если вы хотите отслеживать события на удаленных машинах, просто скопируйте программу osdClient.pl на удаленную машину и запустите ее, указав IP-адрес сервера вместо 127.0.0.1. Обдумайте, какие последовательности указать для проверки на совпадение, если входные данные получены из удаленного источника. Как вариант, можно также задать изображения для каждой конкретной машины, чтобы вы по изображению могли сразу же распознать, с какой машины получено сообщение. Кроме того, можно использовать функцию вывода изображений для отображения графических элементов, понятных только пользователю, например, чтобы вы понимали, что вам пришло сообщение электронной почты, а постороннему человеку, смотрящему на ваш монитор, это изображение ничего не говорило.



Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=6030