内容


用 Ghosd 和 Perl 创建丰富多彩的屏幕显示内容

让系统事件触发显示文本和图像的屏幕警报

Comments

Windows® 和 Linux® 图形化桌面的屏幕显示已经存在多年了。最近 Linux 桌面的无框架透明窗口的进步已经开启了另一个级别的图形化功能。使用平滑字体、真彩色、阴影效果、透明度和图像文件加载,Ghosd 为您提供了实现下一级别的屏幕显示的能力。

使用 Perl 和某些自定义编译的 Ghosd 程序,我将向您展示如何实现您自己的事件通知系统。通过一些简单的关键字匹配和客户机 —— 服务器设置,您可以接收所有系统(远程或本地)的屏幕类型通知。

要求

硬件

2000 年后制造的所有 PC 应当能够提供足够的能力编译和运行代码。如果您已经有了一个图形化桌面,则在桌面中已经有了一个快速的处理器,使您有很好的机会可以在游戏中占尽先机。

软件

Ghosd 程序要求使用 Pango 和 Cairo 库。需要安装这两个库才能执行 Ghosd 编译和配置。查看 参考资料 获得 Cairo 和 Pango 库,或跳到前面并安装一个已经预安装了这两个库的优秀的 Linux 发行版。建议使用 Vector Linux,因为它已经为您预安装并配置了所有库和 Eye Candy 以加速使用 Ghosd 进行操作。

既然已经安装了 Pango 和 Cairo,就需要编译 Ghosd 程序本身。下载并解压缩 Ghosd 源代码归档文件后,用 ./configure && make install 命令编译它。当完成配置和安装过程后,查阅示例目录以获得 Ghosd 的一些使用选项。Ghosd 是部分作为函数库编写的,用于帮助应用程序使用屏幕显示设计隐喻。同样地,提供的示例是小型的 C 程序,用于向您展示如何从命令行使用 Ghosd 以及如何将 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";

这些是位置、文本内容和颜色、字体大小、淡入和淡出速度(以毫秒为单位)及保存显示字符串的数组的默认变量。接下来,我们需要修改文本的显示部分以使用实际指定的颜色。在呈现函数中,将行 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 构建新文本可执行文件。用命令 ./text "red text example" -150 -150 1.0 0.1 0.1 40 500 2000 运行文本 Ghosd 程序示例。示例命令将在 500ms 后淡入“red text example”字符串,字体为红色 40pt,位置为 (-150,-150)。随后,文本将在 2000ms(2 秒)后从屏幕中淡出。

示例目录中提供的图像示例将能够很好地满足我们的目的。尝试执行命令 ./image /usr/share/pixmaps/x264.png -x 40 -y 40,可在屏幕中显示一张简单的图像。下面的图像是同时显示图像和一些文本的示例。

图 1. Ghosd 示例文本和图像
Ghosd 示例文本和图像
Ghosd 示例文本和图像

使用 Perl 和 Ghosd 的屏幕通知程序

一般策略:客户机 —— 服务器策略

Ghosd 程序能够显示可无限变化大小、颜色和样式的文本和图像。要有效地使用该能力监视系统状态、电子邮件和任何其他需要的参数,我们需要保留这种可变性,同时为其使用提供一个简单的接口。下面实现的系统将使用客户机 —— 服务器架构以接收来自本地计算机和远程计算机的显示事件。

消息字符串将由客户机发送,对其进行处理可获得信息关键字(从配置文件中读取),并显示相应的输出。例如,如果服务器收到 New e-mail from mark@developerWorks 字符串,它将查找电子邮件关键字并显示邮件图片,并在右下角显示全部文本。如果客户机发送的消息字符串包含“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 来设置关键字匹配和参数散列。标准的套接字监听代码就位后,将启动主循环以监听新连接。每次传入连接,都将执行配置文件中指定的每个文本和图像类型关键字匹配检查。如果找到匹配,将立即追加完整的命令并执行每个显示事件的完整命令。这种设置将确保为单个事件(例如,新电子邮件中的文本和图像)设置的任何双图像/文本显示将完全同时显示。

配置文件

准备好服务器代码后,您就可以创建自己的配置文件,随心所欲地显示文本了。下面是一个示例配置文件,可以帮助您入门:

清单 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”,则在 -250,-250 位置以 20-point 大小的红色字符编写消息 —— 淡入 100ms 随后在四秒后淡出。图像行将指定图像和显示的坐标,以及关键字“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 连网功能的详细说明,可以参阅很多优秀的文档和 how-to 信息;有关更多信息,请参阅 参考资料

创建这些脚本时(或者从源代码存储库中下载这些脚本时),确保将它们放在 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 中的音轨发生更改时显示当前播放的歌曲名,请遵循以下说明。通过按 Ctrl+P 组合键转至 xmms 中的 Preferences 对话框。单击常规插件选项卡,然后启用 Song Change 插件。单击 configure 并添加以下行:

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

这将通过客户机把当前歌曲标题自动发送给 osdServer.pl 程序。需要把以下行添加到 osdServer.config 文件中,以正确识别 xmms 事件:

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 部分是说跳到文件的末尾并等待新更新。简单的代码行随后将通过 osdClient.pl 程序把字符串发送给 osdServer.pl 程序,前者包含日志文件条目的头 50 个有含义的字节。示例 osdServer.config 文件中的“SYS”是必要的,它允许对所有系统消息执行关键字匹配,而不管其具体内容是什么。

结束语和更多示例

使用这两个更高级示例,您应当能很好地掌握如何将启用了 Ghosd 的屏幕显示服务器和客户机集成到计算环境中。如果需要监视远程计算机上的事件,只需将 osdClient.pl 程序复制到远程计算机上,并用指定的服务器 IP 地址而不用 127.0.0.1 运行该程序。考虑指定字符串来匹配输入是否来自远程计算机源。或者,您可以为特定计算机指定图像,使您可以立即识别出消息来自哪台计算机。此外,您可以使用图像显示功能显示只对用户有意义的自定义图形,让您在收到电子邮件时可以觉察得到,而无需让任何人查看您的屏幕。


下载资源


相关主题

  • 您可以参阅本文在 developerWorks 全球站点上的 英文原文
  • Evan Martin 编写了 Ghosd 程序。
  • Ghosd 要求使用 Cairo 库。
  • 您还需要使用 Pango 才能编译 Ghosd。
  • Linux Journal 有关于 Network Programming with Perl 的优秀指导文章。
  • 浏览 developerWorks 上的所有开源 文章教程
  • 收听针对软件开发人员的有趣访谈和讨论,一定要访问 developerWorks 的 podcast
  • 访问 developerWorks 开源软件技术专区,获得丰富的 how-to 信息、工具和项目更新,帮助您使用开放源码技术进行开发,并与 IBM 产品结合使用。
  • 访问 Safari 在线书店 浏览开放源码技术的各种参考资料。

评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Open source, Linux
ArticleID=208877
ArticleTitle=用 Ghosd 和 Perl 创建丰富多彩的屏幕显示内容
publish-date=04122007