Linux Gazette 2002年5月号
今月のLinux Gazette の記事内容
n今月のニュース
 ・法制化
 ・一般ニュース
 ・ディストリビューション関連ニュース
 ・ソフトウエア及び製品関連ニュース
nウイークエンドメカニック
n ハイパーメディアの道:回顧
n PyGTKを用いる迅速アプリケーション開発
n C++によるGUIプログラミング
n C++によるXlibプログラミング
 
今月のニュース
▼▼▼ 法制化 ▼▼▼
CBDTPA
Electronic Frontier Foundation (電子フロンティア財団)は、CBDTPAのような略語により意味のある解釈を見出す「アルファベット・スープ・コンテスト」の結果 resultsを発表した。当選者 winnersの中には、多くの人がこの立法の裏にある精神として理解するものを旨く纏めたSteven Cherryの「Consume, But Don't Try Programming Anything」(何でも使って良いが、プログラムしようなどとは考えるな)が含まれている。当然ながら、CBDTPA 及び BPDG [EFF リンク] (放送保護討論グループ)などのグループは、法制委員会スポークスマンMimi Devinが法案支持e-メールは一つもなかったと言うように、大変な反対運動に遭遇している globetechnology.com reported 。これは、立案に協力したのは、法案から利益を得る人達だけであることを示す。加えて、数多のウエブサイトがこれら法律の導入に反対する人々の反撃拠点になっている。CBDTPA支持の企業外ウエブペイジはほとんど見あたらない。Catherine Olanich Raymond の最近の記事article は、この広範な反対意見に関し理由付けと背景の解析をしている。
DMCA
DMCAは反消費者だが、研究を犠牲にし兼ねない危険性があることを忘れてはいないようだ。これは Edward Felten vs the RIAAの事件で明らかになった。IEEEの決定により、論文を提出する研究者はその業績がDMCAに違反しないと保証書guarantee that the work を提出するとの注意書きを作成した。しかし、 New Scientist が後で報告したように reported この決定は大衆の反撃を受けた。しかし、スラショットが指摘する pointed out ように、残念ながら反撃は苦情に止まって法的な議論又は権利に基づいていないことだ。これは前向きの発展だが、科学的自由の擁護にはなっていない。
MS政府XP
The Seattle Times reported は米連邦政府が、米国民のオンライン識別の検証にマイクロソフトのパスポート技術を使うことを、考慮中と報じた。これにより、米国民は納税や権利の行使などの際に政府ウエブサイトで自分の身分証明をすることが出来る。これは、パスポート技術の広範な採用を推進して来たマイクロソフトに取って大変な成功だ。これはまた、マイクロソフト製品をITインフラストラクチャの基礎にしようとする政府の広範な計画の一環でもある。これは英国で華々しい成功 significant success を収めた。
 
 
 
 
▼▼▼一般ニュース▼▼▼
Lindows の物議

Lindows はマイクロフトwith Microsoft, と対立しているだけでなく、無料ソフトウエア基金 Free Software Foundation. を完全に運営した。Lindows はその製品のソースコードの頒布にある程度無関心 somewhat casual であったようだ。Bruce Perens は Michael Robertson (Lindows CEO) に対し公開書簡 open letter を書いて、会社を無料ソフトウエア運動の忠実な協力者であるとした。Mono Linux はLindowsの報告と解析を公刊した。上下2部になる。

IP Masquwrade HOWTOの新版を発表

David Ranch は、IP Masquerade HOWTOのリリースを発表した。

変更点は下記である:

・各種の章名を "x2623.html" などから、人の読めるファイル名を使うよう更新
・rc.firewall ルールセット用init.d-スタイル・ スタートアップ・スクリプト
・IPMASQ 勘定の章を拡張
・沢山のURL を更新
・$PORTFWIP バグを修復
2千万ドルのCompaq Linux を獲得
Compaq Computer Corporation (コンパックコンピュータ会社)は、Everyones InternetをホストするRackShackと2千万ドルの3年契約を発表した。コンパックはRackShackのITデータセンタに、工業標準コンパックProLiantサーバーをLinuxベースウエブサーバ、ホストソリューションとして装備する。
 
 
▼▼▼ディストリビューション関連ニュース▼▼▼
Debian
Hewlett-PackardのためのLinuxシステム運営グループ内の技術者/科学者Bdale Garbee,がDebianプロジェクトリーダに選ばれた:

Debian Weekly Newsは最近、Debian GNU/FreeBSD ライブを見たい人のための新ベースtarballをNathan Hawkinsが発表したannouncedと、報じた recently reported 。このポートの状況はここで入手出来る available here.。

Gentoo
Linux Planet は最近、(特に)ソフトウエア開発を楽しむ人々を目標にしたソースベースのディストリビューションを見直した reviewed Gentoo Linux

Gentooはまた、PPCプラットホームに搭載することが出来る。 iMacLinuxが見直した reviewed

Hancom
Linux and Main は、 Eazel (GNEME用にノーティラスグラフィックシェルの生産者)の共同出資者で、韓国のハンコムLinux副社長でもあるBart Decrem とインタビューした。Decremは、韓国のソフトウエア、米国以外の会社及び政府がマイクロソフトに依存し過ぎるのを好まない理由などを論じた。またSlashdotに登場した。ハンコムLinuxと、Linux and Mainはまた、ハンコムLinuxが、初めてアラブ語Linuxディストリビューションを出荷したと報じた。OSNewsの報じるところでは、ハンコムは、ハンコムオフィスパケージに関し完全にLinuxプラットホームに重点を置いている。
 SOT Linux
Linux Todayに、Best Linuxの出版社であるSOTが、ディストリビューション新版の再販に合わせて社名を変更すると発表した記事がある。将来はSOT Linuxとなる筈。
SuSE
SuSE Linux とIBMは、世界中の企業顧客に対し両社が合同でLinuxサポートとサービスを提供する広範なサービス提携を発表した。協定では、IBM Global Services とSuSEは、サポートと専門家サービスで協力する。IBMはSuSEのエキスパート開発、保守及び支援チームの援助を得て、SuSE Linuxインタープライズサーバーのターンキイ実現をパケージしてサポートする。このサービス提案に加えて、両社は顧客契約で協力し、互いに技術を補完して、企業顧客に対し威力を発揮する。

Slashdot に、 SuSE 8.0 が出荷され、KDE 3.0, kernel 2.4.18, その他各種の更新/強化を含んでいるとの記事 story があるt。

 
 
 
 
▼▼▼ソフトウエア及び製品関連ニュース▼▼▼
マッキントッシュPostgreSQLがリリース
Command Prompt, Inc.からのMammoth PostgreSQLは、SQL互換オブジェクトリレーショナルデータベース管理システム(ORDBMS)である。これは、中小規模の事業に、望みの力、性能及びオープンスタンダードサポートを与える設計となっている。PostgreSQL 7.2.1リリース、Mammoth PostgreSQL、と完全互換なので、Solaris、MacOS X 及び Red Hat Linux x86プラットホームのため完全にサポートされたPostgreSQLディストリビューションを提供する。Mammoth PostgreSQLは、SSL接続(ネイティブ及びODBC)に関する組み込みサポートと同時に、C/C++、Perl、Python用のAPIを付けて出荷される。即売用にオンラインと加入者ベースのライセンスモデルが利用出来る。

Command Prompt, Inc. は、 PostgreSQLに関するサポート、プログラミング及びサービスを提供する。サービス契約と同時に、タイム及び物質サポートが得られ、カスタマのデータベースソリューションのため単一地点会計責任が可能になる。

Linuxの成長がEtnusのツール販売を刺激
複雑なコードのためのデバッガ供給者であるEtnusは、インテルLinuxプラットホーム上のTotalView デバッガが、Linuxシステム上で複雑で必須のコードを開発するのが増えるにつれ、売上高記録を更新したと、発表した。Etnus TotalView デバッガの販売量とライセンス数の双方が2001年第一四半期に倍増し、Linux向けが最高売上であったと発表した。Etnus TotalView はC/C++とフォートランをサポートする、クロスプラットホームの最高技術デバッガである。

Etnus は、自分のサポートするプラットホームの中ではLinux がリーダーであり続けそこでの機能性を増すと考えている。TotalView の次のリリースは、will add support for GCC 3.X 及びLinux用インテルコンパイラに関するサポートにを加えるであろう。

CylantSecure
CylantSecure は、OSの動きを監視して攻撃が起こる前にそれを止めるLinux及びUNIX変形体用の侵入検出システムである。Software Systems Internationalの一部門、Cylant、が開発して生産して来た。kernelに計器を付け加えることにより、Cylantはサーバー行動パターンを測定して、作動中の変化を検出することが出来る。異常な行動パターンが起こると、リアルタイムでこれを停止し、攻撃を実行前に防止する。

この技術は、ほとんどの攻撃が食い物にされるソフトウエアの行動を測定可能な方法で変えてしまうとの原理に基づく。CylantSecureは、ソフトウエアの行動監視にセンサを、行動の異常性を発見する統計的解析エンジンとともに用いる。連続的な行動監視を通じて、CylantSecure は管理者に攻撃の早期警報を発するので。適切な対策を取ることが出来る。子のような対策には、プログラムの活動停止、攻撃IPからの交信回避、システム状態解析などが含まれる。詳しい情報は、Cylant websiteへ。

Linux用Opera 6.0ベータ2をリリース
Opera Software ASA は、Linux用Opera 6.0ベータ2をリリースした。数々の特徴がありスピードを向上して世界中のLinuxユーザーを喜ばせる。Linux用Operaの早期のバージョン、Opera5、はダウンロード・インストレーションが百万人に達する金字塔を建てた。
Linux用Opera 6.0ベータ2の完全な変更ログは、http://www.opera.com/linux/changelog/
McObjectのeXtremeDB 2.0
McObject は、Linux上メインメモリデータベースeXtremeDBのバージョン2.0をリリースし、開発者の融通性を改善し、eXtremeDBに基づくアプリケーションのランタイム能力を強化した。 McObject は、eXtremeDBをスタートラインから構築して、インテリジェントな接続装置に関するCPUとRAMの束縛に合わせる一方で、在来のデスクベース・データベースシステムを超える劇的な性能を提供する。eXtremeDB 2.0 の評価版は無料でwww.mcobject.com/download から入手出来る。
Mozilla
Mozilla 1.0リリース候補1がリリースされた。これは、来るべき1.0リリースの試験版で、その日の近いことを示す。Mozillaは、相変わらずタイムマガジンの注意を引いており、同誌はMozillaのリリースによりブラウザ戦争の停戦が破られると報じている。
Arkeia が新しいバージョン5ベータをリリース
Arkeia Corporation が新しいArkeia 5ベータバージョンをリリースした。Arkeiaバージョン5は、世界中に90,000人のユーザーを有する高性能、多重プラットホームソフトウエアであるバージョン4xの後継である。Arkeia 5は、プログラムアーキテクチャを全く書き換えており、ユーザーの要求に応えた新機能の組合せを含むことを特徴とする。
その他のソフトウエア

Apache 2.0が、公式に安定した is now, officially, stable.

Galeon 1.2.1 がリリースされた been released

AbiWord 1.0が出た is out

Mailmanの新バージョン (バージョン 2.0.10)が入手出来る is now available.

 

Copyright © 2002, Michael Conry and the Editors of Linux Gazette.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 78 of Linux Gazette, May 2002
 
 
 
 
ウイークエンド・メカニック

By Thomas Adam

目次

5月版へようこそ

簡単な紹介:Suid

簡単な紹介:SquidGuard

重要ファイル:簡便 BASH バックアップスクリプト

プログラム検討:Nedit

お終いの時間

5月版へようこそ

[ **この版は 助けて呉れた友人Natalie Wakelin に捧げる。彼女は私の輝きの星で親友だ。彼女には「技術文書」の意味が理解出来ないだろうが、それでも捧げる。有り難う** ]


暫くお休みを頂いたが、やっと自由の世界と大学生活に飛び込んだ。生活を合わせるのは始めに想像したより難しい。

それは兎も角……

Linuxの中で如何に奇妙に見えようとも、Linuxで解けない可能性はないのにに最近気付いた。

大学の学業とは別に、私はHants LUGで個人的及びメールで問題解決に協力している。大変面白い。沢山のことを学んだ。

前書きはこの位にして、先へ進もう。

簡単な紹介:Squid                目次へ戻る

Squidとは?

インストレーション

コンフィギュレーション

フィルタリング(アクセス制御)

Squidのインストール

Squidとは?

9月版Septemberを読まれた方はApache の使用について記事を書いたのを覚えておられるだろう。色々な反響を頂いた。 squidを解説するのが良いと思った。

ご存じない方のために言うと、(海のイカではない)Squid はLinuxインターネット代用プログラムだ。squid と呼ぶのは(良い名前を人が先に使ったからだろう)

Squidは、(プロキシサーバーと言う)マシンを使ってインターネット要求をチャンネルする。

さらにSquidは、特定のウエブペイジを読めるようにも読めないようにもフィルタfilter する能力がある。これは、ACL (Access Control Lists)を通じておこなう。詳しくは後で。

インストレーション

squid のインストールは一本道だ。squid は主要ディストリビューション(RedHat, SuSE, Caldera, Debian, など)すべてと一緒に供給されるので、ディストリビューションCDから簡単にアクセスすることが出来る。

RPM フォーマットをサポートするディストリビューションを持っている人は、次のコマンドを使ってインストールされているか否かをチェックすることが出来る:



rpm -qa | grep -i squid


搭載されていれば、 "squid2-2.2.STABLE5-190" (又は類似)が返る筈だ。返事がなければ、ディストリビューションCDからsquidをインストールする。

ディストリビューションCDにsquidがないか、又はRPMフォーマットをサポートしないLinuxを使っているときは、.tgz(tar.gz)のソースを、http://www.squid-cache.org/からダウンロードする。

Squidをソースからインストールするには、"/tmp" にtar ballして次のコマンドを出す:



1. "root" のユーザーでなければ、rootとしてsu 又はlog in する


2. cd /tmp


3. tar xzvf ./name_of_squid.tar.gz -- [or possibly .tgz]


4. Now run:





./configure





5. これらの後、エラーがなければ、単に:





make && make install





とタイプしてコンパイルしファイルをインストールする。


一般的に、標準RPMインストレーションからは、これらのディレクトリを使う:



/usr/bin


/etc


/etc/squid (多分 -- RH 5.0の下にあるのが普通)


/var/squid/log/


[/usr/local/etc] <-- 多分 "/etc" に symlinkeされている


ソースからコンパイルするのであれば、沢山のファイルが出来上がる:



/etc


/etc/squid (多分 -- RH 5.0の下にあるのが普通)


/usr/local/bin


/var


[/usr/local/etc] <-- 多分 "/etc" に symlinkeされている


言うまでもないが、特に要求されない限り、これでファアイルが終わる。

これでSquidがインストールされた。次のコンフィギュレーションに入る。

コンフィギュレーション

プロキシサーバーになるため、なすべきことは未だ沢山ある。

作業を一つのファイル /etc/squid.confに集中する。Squidの設定すべてを維持するファイルだ。このファイルを編集するので、元のファイルのコピイを取っておくのが良い。それには次のコマンドを出す:



cp /etc/squid.conf /etc/squid.conf.orig


次いで、好みのエディタを起動し、squid.confのエディットを始める。

Squidを走らせるのにこのファイルを「ボックス外」で使うのは不可能だ。直ぐ働くプロキシサーバーを入手する前にコンフィギュアしなければならないことが沢山ある。一目で見て、このファイルの長さは1マイルもあるが、開発者のお陰で、ファイルの大部分は利用出来るオプションについてのコメントである。

最初に、Squidに対し作動しポートを聴取するマシンのIPアドレスを告げる。squid.confの中に、次のようなコマンド行がある筈だ。、



#http_port 3128


始めの#記号を削除して、この行のコメントを外す。規定値で、ポート番号3128が選ばれる。しかし、Squidに違うポートを聴取させたいときは、それを変える。そこで、私のプロキシマシンでは、次のように規定した:



http_port 10.1.100.1:8080


これは、squidにポート8080を使って上記IPアドレスを聴取させる。注意しなければならないのは、同じポートを他の作動中アプリケーションが使用しないことだ。多くの人がこの間違いを犯す。

ここで、このコンフィギュレーション・ファイル全体を通って進むので、ここで変更しなければならない主なオプションはcache_memである。このオプションは、キャッシュなどにどれほどのメモリを使うかをsquidに告げる。

私はこの行のコメントを外して−−8MBの規定値を残した。

このオプションの遙か下に、幾つかオプションがあってsquidにキャッシュ"watermark"の高/低を告げる。これは単にディスク空間のパーセンテージで、90/95%以内に入ったときsquidはキャッシュした項目の幾つかを削除し始めることを意味する。



#cache_swap_low  90




#cache_swap_high 95


私は単純にこれらのコメントを外したが、値は次のように変えた。理由は、私が持っているのは60GBハードディスクで1パーセントが数百MBになるからである:



cache_swap_low  97




cache_swap_high 98


これで、squidに、聴取IPポートと、使うメモリと、キャッシュ項目削除を始めるメモリ空間のパーセンテージを告げた。ここでファイルをセーブする。

次に最後から2番目で私の変えたオプションは、キャッシュディレクトリの位置と大きさを決めるので極めて重要だ。次のようなTAGがある:



cache_dir /var/squid/cache 100 16 256


これは、パス"/var/squid/cache"各トップレベルディレクトリが100MBを拘束するとの意味だ。16個のトップレベルディレクトリあり、その下に256個のサブディレクトリがある。

フィルタに移る前に、このファイルでひねらなければならないのは、アクセスログの使用だ。cache_dirのためコンフィギュアしたオプションの真下に、ロギングを許すオプションがある。一般的に次のロギングオプションを持っている:

・access log
・cache log
・store log
・swap log

上のログの各々は、プロキシサーバー運営の際それぞれ長所/短所がある。一般的に、保留するログは access logs とcache log だ。理由は簡単で私がstore とswap logには関心がないからだ。

ユーザーがおこなうリクエスト(ユーザーの行きたいウエブペイジ)をログするのはaccess logファイルだ。私が未だ高校にいた頃、このファイルは、どのユーザーが禁制サイトに入ろうとしているかを知るのに大変貴重だった。システム管理者にこのファイルを働かせることをお薦めする。大変役に立つ。

そこで、(TAGSのコメントを外して)次をおこなった:



cache_access_log /var/squid/logs/access.log




cache_log /var/squid/logs/cache.log


ログ名はそのままにすることを薦める。

明らかに、squid.confファイル内の基本オプションのほとんどを終わっただけなのは明らかだ。特定の状況のため膨大なオプションがある。それぞれのオプションには、良いコメントがあるので、特定のオプションの役割は分かる筈だ。難しくない。

フィルタリング(アクセス制御)

この章でもまだ "/etc/squid.conf" を使うが、アクセス制御のためのコンフィギュレーションオプションに少し詳しく踏み込む。

アクセス制御は、システム管理者に、どのクライアントがプロキシサーバーに実際接続出来るかを、IPアドレスやポートなどで、制御する方法を与える。大きいネットワーク構成のコンピュータにとって有用である。

一般的にACL (アクセス制御リスト) はそれらに対し次の特性を持っている:

・src - ソース即ちクライアントのIP アドレス
・dst - 相手先即ちサーバーの IP アドレス
・srcdomain - ソース即ちクライアントのドメイン名
・dstdomain - 相手先即ちサーバーのドメイン名
・time - 曜日と時刻
・url_regex - URL 正規表現パターン整合
・urlpath_regex - URL-パス正規表現パターン整合、プロトコルとホスト名は省略
・proxy_auth - 外部処理を通じるユーザー認証
・maxconn - 単一クライアントIPアドレスからの接続最大数制限

アクセス制御はすべてこれらに対し次のフォーマットを有する:



acl   acl_config_name   type_of_acl_config values_passed_to_acl


そこでコンフィギュレーションファイル内に、次の行を見付ける:



http_access deny all


そして、その上に次の行を加える



acl weekendmechnetwork 10.1.100.1/255.255.255.0




http_access allow weekendmechnetwork


"weekendmechnetwork"の名は、自分の選んだ名に変えることが出来る。ここでおこなっているのは、"weekendmechnetwork"の名を持つすべてのaclについて、255.255.255.0のnetmaskとともに、特定のIPアドレス10.1.100.1を用いると言っている。従って、ネットワーク上でクライアントに割り当てられた名は"weekendmechnetwork"となる。

"http_access allow weekendmechnetwork" の行は、ルールが有効で、squid自体で解析することが出来ることを示す。

次ぎにしなければならないのは、選ばれたクライアントにインターネットへのアクセスを許すことも見ることだ。これは全部のマシンをインターネットに接続するとは限らない場合に有用だ。

今まで付け加えたことの下で、イカのようなことを規定することが出来る:



acl valid_clients src 192.168.1.2 192.168.1.3 192.168.1.4




http_access allow valid_clients




http_access deny !valid_clients


ここで言っているのは、src IPアドレスがリストに載っているACL名 "valid_clients" については、"valid_clients" へのhttpアクセスを許し(http_access 許可valid_clients)、リストに載っていないその他のIPには許さない(http_access 拒否 valid_clients)ことである。

すべてのマシンにインターネットアクセスを許すのであれば、次のように規定する:



http_access allow all


しかし、ACLを更に拡張して、squidに一定のACLが特定の時期だけ働くようにすることが出来る。例えば:



1.   acl clientA src 192.168.1.1


2.   acl clientB src 192.168.1.2


3.   acl clientC src 192.168.1.3


4.   acl morning time 08:00-12:00


5.   acl lunch time 12:30-13:30


6.   acl evening time 15:00-21:00


7.   http_access allow clientA morning


8.   http_access allow clientB evening


9.   http_access allow clientA lunch


10.  http_access allow clientC evening


11.  http_access deny all


[ ** 注意:上の行番号は説明の便のためのみなので、挿入するときは外すこと** ]

Lines 1-3 は、マシンを特定するACL 名を設定する
Lines 4-6 は、規定時間制限(24時間制)でACL を設定する
Line 7 は、cliant A (でcliant Aのみ) に「朝」の時間帯にアクセスを許す意味
Line 8 は、cliant B (でcliant Bのみ) に「夕方」の時間帯にアクセスを許す意味
Line 9 は、cliant A (でcliant Aのみ) に「昼」の時間帯にアクセスを許す意味
Line 10 は、cliant C (でcliant Cのみ) に「夕方」の時間帯にアクセスを許す意味
Line 11 は、他のcliantのいずれかが接続使用とすると−拒否する意味

だがさらに、URL表現の中の特定のregexe に一致させることをSquidに命令して、事実上リクエストをビン(詳しくは−"&>/dev/null")の中に投げ入れることにより、ACLを用いる。

これをおこなうには、特定のパターンを持つ新ACLを規定することが出来る。例えば:



1.  acl naughty_sites url_regex -i sex


2.  http_access deny naughty_sites


3.  http_access allow valid_clients


4.  http-access deny all


[ ** 注意-- 上と同じく行番号は使わないこと!! ** ]

Line 1 は、条項url_regex が−つまりURL内に含まれる語をチェックし結果−そのACLがその型であると言うACL 名" naughty_sites" には "sex" の語が結び付いていると言う。 -i は、ケースセンシティビティを無視する意味。
Line 2 は、 ACL "naughty_sites"からの何かを含むウエブサイトへのアクセスは全部のクライアントにきょひするとの意味
Line 3 は、"valid_clients"からのアクセスを許す意味
Line 4 は、その他すべてのリクエストを拒否する意味

「一つより多いregexはどう規定するか」との疑問があると思う。答は簡単だ。別のファイルに入れることが出来る。例えば、次の言葉をフィルタし、それがURLに現れたらアクセスを拒否したいとする:



sex


porn


teen


それをファイル(一度に一単語)



/etc/squid/bad_words.regex


に入れて、"/etc/squid.conf" の中で次のように規定する:



acl bad-sites url_regex -i "/etc/squid/bad_words.regex"


http_access deny bad_sites


http_access allow valid_clients


http-access deny all


これで楽に生きられる。つまり必要なとき何時でも単語をリストに加えることが出来る。

SquidGuardと言う名のプログラムを使って、regexとドメイン名の両方をフィルタする遙かに易しい方法もある。後で詳しく述べる。

Squidのインストール

実際にSquidを走らせる最も重要な部分に差し掛かった。残念ながら、初めてsquidを初期化するのであれば、渡さなければならない幾つかのオプションがある。一般的にsquidに渡すべきオプションは、次の表に纏めることが出来る:

フラッグ 説明
-z
 
squidに必要な swap ディレクトリを作る。squidを初めて働かせるとき、又はキャッシュディレクトリが削除されたときだけ使う
-f
 
このオプションは規定値"/etc/squid/conf" 以外に使用する代替ファイルを規定することが出来るが、使うことは稀である
-k reconfigure

 
このオプションはsquidに、squidデーモン自体を停止することなく、コンフィギュレーションファイルをロードし直すことを命じる
-k rotate
 
このオプションはsquidにログを回転して新しいものをスタートさせることを命じる。cron ジョブに役立つ
-k shutdown Squidの実行を停止する
-k check squid デーモンがあって働いていることを点検し確認する
-k parse "-k reconfigure"と同じ

利用することの出来るオプション全体は次の通りである:



用法: squid [-dhsvzCDFNRVYX] [-f config-file] [-[au] port] [-k signal]


       -a port   HTTP ポート番号を規定 (規定値: 3128).


       -d level  stderr にもまたデバッグを書き込む


       -f file   与えられた config-file を、次ぎの代わりに利用する


                 /etc/squid/squid.conf


       -h        ヘルプメッセージをプリントする


       -k reconfigure|rotate|shutdown|interrupt|kill|debug|check|parse


                 コンフィギュレーションファイルを解析して、働いている


                 copy (-k parseを除く) に信号を送って終了


       -s        syslogに対するロギングを有効にする


       -u port   ICP ポート番号を規定(規定値:3130)、0で無効にする


       -v        バージョンをプリント


       -z        swap デイレクトリを作る


       -C        致命的な信号をキャッシュしない


       -D        初期 DNS テストが出来ないようにする


       -F        フォアグラウンド急速記憶再構築


       -N        非デーモン・モード


       -R        ポートに REUSEADDR を設定しない


       -V        仮想ホストhttpd-アクセラレータ


       -X        完全デバッグを強制


       -Y        急速再ロード中に UDP_HIT or UDP_MISS_NOFETCH にだけ戻る


squid を初めて走らせるのであれば、ユーザー"root"にログインして、次をタイプする:



squid -z


これでキャッシュが作られる

続いて次のコマンドを送る:



squid


これで、プロキシサーバーが走る。上出来だ!!

 

簡単な紹介:SquidGuard              目次へ戻る

SquidGuareとは?

インストレーション

コンフィギュレーション

SquidGuardとは?

SquidGuardは、それを使ってsquidが自分に送られたリクエストをが外部SquidGuardデーモンに送る「リダイレクトプログラム」である。SquidGuardの仕事は、Squid自体より大きいフィルタリングが出来るようにすることである。

しかし、フィルタリングをおこなうのに、単純なフィルタにはSquidGuardは必要でないことを指摘しておかなければならない。

インストレーション

SquidGuard は(ほぼ十分に) http://www.squidguard.org/downloadから入手することが出来る。このサイトにはSquidGuardのコンフィギュアの仕方に関する情報が豊富にある。

Squidのように、SquidGuard はrpm と.tgz フォーマットの双方で入手することが出来る。

君のディストリビューションがRPMをサポートしていれば、次の方法でインストールすることが出来る:



su - -c "rpm -i ./SquidGuard-1.2.1.noarch.rpm"


RPM フォーマットをサポートしていないときは、次の方法でソースをダウンロードしてそれをコンパイルすることが出来る:



tar xzvf ./SquidGuard-1.2.1.tgz


./configure


make && make install


ファイルは、"/usr/local/squidguard/"の中にインストールする。

コンフィギュレーション

メインの"/etc/squidguard.conf"を実際にいじる前に先ず、お馴染みの"/etc/squidguard.conf"を少々変更しなければならない。ファイルの中に次のTAGを置く:



#redirect_program none


このコメントを外し、語「none」をメインSquidGuardファイルへのパスで置き換える。メインファイルの場所が分からないときは、次のコマンドを送る:



whereis squidGuard


次いで、適切なパス名とファイル名を入れる。これで、次のようになる筈だ:



redirect_program /usr/local/bin/squidGuard


ファイルをセーブして、次をタイプする。



squid -k reconfigure


これでコンフィギュレーションファイルが再ロードされる。

ここで、面白いことが始まる。送られたリクエストをフィルタするのに、リダイレクトプログラムを使うことをsquidに告げたので、それに適合するルールを定義しなければならない。

SquidGuardのメインコンフィギュレーションファイルは "/etc/squidguard" である。ボックスの外で、これは次のように見える:

-------------------

(テキスト版)



logdir /var/squidGuard/logs


dbhome /var/squidGuard/db





src grownups {


    ip     10.0.0.0/24    # range 10.0.0.0  - 10.0.0.255


              # AND


    user   foo bar    # ident foo or bar


}





src kids {


    ip     10.0.0.0/22    # range 10.0.0.0 - 10.0.3.255


}





dest blacklist {


    domainlist blacklist/domains


    urllist    blacklist/urls


}





acl {


    grownups {


    pass all


    }





    kids {


    pass !blacklist all


    }





    default {


    pass none


    redirect http://localhost/cgi/blocked?clientaddr=%a&clientname=%n&clientuser=%i&clientgroup=%s&targetgroup=%t&url=%u


    }


}


-------------------

しなければならないのは、コンフィギュレーションファイルを区切って、各部分の作用を説明することだ。



logdir /var/squidGuard/logs


dbhome /var/squidGuard/db


1行目は、ログファイルの現れるディレクトリを設定し、存在しなければそれを作る。

2行目は、禁止サイト、表現などを記憶するディレクトリを設定する。



src grownups {


    ip     10.0.0.0/24    # range 10.0.0.0  - 10.0.0.255


              # AND


    user   foo bar    # ident foo or bar


}


上のコードブロックは、多数のことを設定する。src "grownups" は、IPアドレス範囲を規定し、どのユーザーがこのブロックのメンバーであるかを示して定義する。便宜のため、一般的な用語"foo" と"bar"をここでは例として使用する。

user TAG は、squidプロキシバーにリクエストを送るサーバー上でidentサーバーが走っているときだけ使用することが出来、そうでないときは無効てあることに、注意しなければならない。



src kids {


    ip     10.0.0.0/22    # range 10.0.0.0 - 10.0.3.255


}


別のブロックを設定する。今回は、"kids"と呼ばれ、これはIPアドレスの範囲で決定されるが、ユーザーはいないブロックである。

grownupskids を"/etc/squid.conf"で見出されるようなものと同様のACL名と考えることが出来る。



dest blacklist {


    domainlist blacklist/domains


    urllist    blacklist/urls


    expression blacklist/expressions


}


ステートメントのこの部分は、特定のフィルタ処理に対するdestリストを定義するので、重要である。処理により、SquidGuardがフィルタ処理を適用する三つの主な方法がある:

1.domainlist−ドメインをそれだけ、1回に1行リストする、例えば:



nasa.gov.org


squid-cache.org


cam.ac.uk


2.urllist −実際に特定ウエブペイジを規定する("www"は省略)、例えば:



linuxgazette.com/current


cam.ac.uk/~users


3.expression−URLの中で禁止すべき単語をregexする、次の通り:



sex


busty


porn


コードの最後のブロック:



acl {


    grownups {


    pass all


    }





    kids {


    pass !blacklist all


    }





    default {


    pass none


    redirect http://localhost/cgi/blocked?clientaddr=%a&clientname=%n&clientuser=%i&clientgroup=%s&targetgroup=%t&url=%u


    }


}


は、acl ブロック及び "grownups" のため、すべてのリクエストを通過させる−つまり、これらのURLの destブラックリストに含まれる/表現など許す、ことを命じる。

次いで、"kids" 部分のため、dest blacklists除くすべてのリクエストを通すことを命じる。この点で、URLがdest blacklistsに一致すると、defaultに送られる。

default部分は、リクエストが" grownups" 又は "kids" から来たものでないと見出したときは、ウエブサイトへのアクセスを許さず、エラーペイジなど別のウエブペイジに送り直すことを命じる。

これら送り直しステートメントと一緒に渡される変数は、リクエストの型などを規定し、次いでこれをcgiスクリプトが処理して、習慣的なエラーメッセージなどを作る。

フィルタを起こすためには、この時、redirectクローズに伴い又は伴わないで、次のコードがなければならないことに注意:



default {


  pass none


}


もっと進んだコンフィギュレーション・オプションをこのファイルの中で使用することが出来る。その例はt http://www.squidguard.org/configurationにある。

これで Squid 及び SquidGuard双方に関する講義を終わる。情報はすべて、この文書に埋め込んだURL及び、私のウエブサイトにある http://www.squidproxyapps.org.uk/

 

重要ファイル:簡便 BASH バックアップスクリプト  目次へ戻る

「別のバックアップスクリプトはないか」との質問がある。そこに飛ぼう。

スクリプトは全く簡単だ。バックアップしたいファイル(及びディレクトリ)すべてを一覧するコンフィギュレーション・ファイル(平文)を使い、次いでそれらをgzippしたtarballの規定の場所に入れる。

BASHシェルスクリプトに慣れている人は、繰り返しだと思うだろうが、行間のコメントがシェルを習おうとする人の役に立つと思う。

-------------------

(Text Version)



#!/bin/bash


#################################################


#Keyfiles - tar/gzip configuration files        #


#Version:   Version 1.0 (first draft)           #


#Ackn:      based on an idea from Dave Turnbull #


#Authour:   Thomas Adam             #


#Date:      Monday 28 May 2001, 16:05pm BST     #


#Website:   www.squidproxyapps.org.uk           #


#Contact:   thomas@squidproxyapps.org.uk        #


#################################################





#此処のコメントはDave Turnbullの利益のため:





#変数宣言


configfile="/etc/keyfiles.conf"


tmpdir="/tmp"


wrkdir="/var/log/keyfiles"


tarfile=keyfiles-$(date +%d%m%Y).tgz


method=$1           # "keyfiles"に渡されるオプション


submethod=$2        # "$1" と一緒に供給されるオプション


quiet=0             # 冗長の上でターン(規定値)





cmd=`basename $0`   #ファイル名からパスを剥ぎ取る


optfiles="Usage: $cmd [--default (--quiet)] [--listconffiles] [--restore (--quiet)] [--editconf] [--delold] [--version]"


version="keyfiles: Created by Thomas Adam, Version 1.0 (Tuesday 5 June 2001, 23:42)"





#エラー点検を扱う・・・


if [ ! -e $configfile ]; then


  for beepthatbell in 1 2 3 4 5; do


    echo -en "\x07"


    mail -s "[Keyfiles]: $configfile not found" $USER


  done


fi





#作業用ディレクトリがあることを確認


[ ! -d $wrkdir ] && mkdir $wrkdir





#コマンド行経由で送られたオプションを解析


if [ -z $method ]; then


  echo $optfiles


  exit 0


fi





#コマンド行シンタックスを点検


check_syntax ()


{


  case $method in


    --default)


    cmd_default


    ;;


    --listconffiles)


    cmd_listconffiles


    ;;


    --restore)


    shift 1


    cmd_restore


    ;;


    --editconf)


    exec $EDITOR $configfile


    exit 0


    ;;


    --delold)


    cd $wrkdir && rm -f ./*.old > /dev/null


    exit 0


    ;;


    --version)


    echo $version


    exit 0


    ;;


    --*|-*|*)


    echo $optfiles


    exit 0


    ;;


  esac


}





#ここから作業開始・・・


# "--default"設定を使用するファンクションを宣言


cmd_default ()


{





  # $configfileに含まれるファイルすべてをar/gz


  


  if [ $submethod ]; then


    tar -cZPpsf $tmp/$tarfile $(cat $configfile) &>/dev/null 2>&1


  else


    tar -vcZPpsf $tmp/$tarfile $(cat $configfile)


  fi


  


  # デイレクトリの内容が空白であるとき・・・


  if test $(ls -1 $wrkdir | grep -c -) = "0"; then


    mv $tmp/$tarfile $wrkdir


    exit 0


  fi


  


  for i in $(ls $wrkdir/*.tgz); do


    mv $i $i.old


  done


 


  mv $tmp/$tarfile $wrkdir 


}





# $configfileに含まれるファイルのリストを作る


cmd_listconffiles ()


{


  sort -o $configfile $configfile


  cat $configfile 


  exit 0


}





#ファイルを記憶し直す・・・


cmd_restore ()


{


  cp $wrkdir/keyfiles*.tgz /


  cd /


  


  # quiet フラッグを点検


  if [ $submethod ]; then


    tar vzxfmp keyfiles*.tgz &>/dev/null 2>&1


    rm -f /keyfiles*.tgz


    exit 0


  else


    tar vzxfmp keyfiles*.tgz


    rm -f /keyfiles*.tgz


    exit 0


  fi


}





# main ファンクションを呼び出す


check_syntax


-------------------

しなければならない変更は、次の変数に対してだと言えば充分だろう:



configfile="/etc/keyfiles.conf"


tmpdir="/tmp"


wrkdir="/var/log/keyfiles"


しかし、私のスクリプトは十分に賢く、$wrkdirの有無を点検して、なければ作る。

適切なパーミッションをおこなったが確認しなければならない、次のようにする:



chmod 700 /usr/local/bin/keyfiles


最も重要なファイルは、スクリプトのコンフィギュレーションファイルで、私の場合は次のようになっている:

-------------------

(Text Version)



/etc/keyfiles.conf


/etc/rc.config


/home/*/.AnotherLevel/*


/home/*/.fvwm2rc.m4


/home/solent/ada/*


/root/.AnotherLevel/*


/root/.fvwm2rc.m4


/usr/bin/header.sed


/usr/bin/loop4mail


/var/spool/mail/*


-------------------

このファイルが tar プログラムに渡された後、上のファイルのようにワイルドカードの使用が有効になる

スクリプトが走る度に、最新のバックアップファイルが作られる、つまり新しいファイルが生まれる前に"keyfiles-DATE.tgz"の名が、"keyfiles-DATE.tgz.old"に変わることを、言っておかなければならない。

これは、何時でもバックアップファイルを記憶する必要がある時のためで、私のスクリプトは、".tgz" 拡張子を点検することにより、どのファイルを使うかが分かる。

この特徴のため、ディレクトリから古いファイル全部を削除する "--delold"オプションを含めた。

プログラムを使うには、次のようにタイプする:



keyfiles --default


これはバックアップ処理を開始する。冗長を押さえたいなら、フラッグkeyfiles --default --quietを付け加える。

このプログラムが採用するその他のオプション、ほとんど自明である。

このバックアップスクリプトは、決して完全でなく、もっと良いものがある。ご意見を歓迎する。

プログラム検討:Nedit               目次へ戻る

遙かな昔、この雑誌の創始者John Fisk がこの欄に執筆しており、別の著者Larry Ayers が一連のプログラム検討をしていた。彼はNeditと言う名の新プログラムを簡単にのべたが、検討しなかった。そこで、私がおこなう。

私はNedit を3年ほど使っている。このスクリーンショットthis screenshotのような、Neditの典型的ウインドウであるX11にいるとき、全部の仕事をその中でおこなっている。

このプログラムでは、色々な特性を選択することが出来る。最も有名なのは以下のような多数の言語に関するシンタクス強調特性であろう。

・C
・C++
・Java
・JavaScript
・Ada
・Fortran
・Pascal
・Lex
・Yacc
・Perl
・Python
・Tcl
・Awk
・Sh Ksh Bash
・Csh
・Makefile
・SGML HTMK
・LaTeX
・Postscript
・SQL
・Matlab
・VHDL
・Verilog
・Xresources
・Nedit Macro
・CSS
・Regex
・XML

何か変な理由で、上のリストに載っていない変な言語でプログラムするときは、自分のregexパターンを規定することが出来る。

Nedit もまた、大文字と小文字を区別するregexパターン一致により、複雑な検索をして方法を置き換えることが出来る。

一般的な検索/置き換えダイアログボックスは、次のようで、複雑な検索が出来るようになっている:

  此処にある筈の図は原文でも何故か消えている

各メニューはトムオフっしてウインドウに残すことが出来る。これは特定のメニューを何度も使い、その度にクリックするのが面倒なとき、特に役立つ。えん

このプログラムは、有用なオプション幾つかを付けてロードすることが出来る、私は全部を使い切っていない。それでもが十分でないかのように、Neditは特注マクロを書いてもっと不思議な機能を定義することが出来るようになっている。

このプログラムを万人にお勧めする。Emacs / Vimに再投資しようとは思わないが、メモリを食い過ぎるて高価な"X11-Emacs"パケージに対する有望な代替物だと思う。

Nedit はhttp://www.nedit.org/から入手出来る。

お終いの時間                  目次へ戻る

これで今月は終わり。こんなに長くなるとは思わなかった。私の大学生活は近く終わる。試験が5月末にある。その後、Linuxについてのアイデアを追求する夏が来る。

次回まで!

ご意見を下さい

下のe-メールアドレスをクリックしてご意見を下さい

mailto:thomas_adam16@yahoo.com

 

Copyright © 2002, Thomas Adam.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 78 of Linux Gazette, May 2002
 
 
 
 
ハーパーメディアの道回顧

By Ronnie Holm

‥‥未来の道を照す。この記事は、ハイパーメディアの世界と、先駆者の業績に対し歴史的建アーキテクチャ的予想を加える。ハイパーメディアの考えは、45年前の世界的ウエブに遡るので、この記事はそれらの業績の記述から始める。ハイパーメディアなる用語の定義を集めた人はいないが、この記事では、先駆者の考えから導かれる定義を幾つか与える。

その後で、実際のハイパーメディアのアーキテクチャ革命の主な段階を説明する。その部分を読むときは、ソフトウエアの一般的発展方法を心に留めること(集中式からモジュール式へとは別に)。これがハイパーメディアシステムい発展に反映されてるのは当然だ。

1940年代:Vannevar Bush とMemex

40年代中頃、人類の知識の蓄積が急速に大きくなった。これにより、情報を効率よく認識し易い方法で記憶するのが極めて難しくなった。Bush [1] は、「情報過剰」の問題に気付き、情報の記憶、組織及び再現に関する空想的解決策を見出した。人間の脳特に記憶力のような連想の原理で働く機械を工夫した。Memex (Memory extensionの略)と言うこの機械は、Bushを後にテキストを扱うときハイパーテキスト及び何種類ものメディアを混ぜるときのハイパーメディアと呼ばれる分野の先駆者に仕上げた。今日、用語ハイパーテキストとハイパーメディアとは、同じ意味で用いられる。

ハイパーテキストの原理は文学で良く知られた概念だ。テキストを次々に真っ直ぐ読むのとと同時に、別の材料の脚注、注記、別の資料の参照に飛ぶことが出来る。Bushは、テキストのその部分に触ると、真っ直ぐ読むのから離れて、直接脚注、注記、又は別の資料に飛ぶことを考えた。この読み方は、情報管理の世界のハイパーテキストの定義に頼っている [2]。読者が入手出来ない資料など、読者が物理的に引照するが難しい場合や不能な場合は、電子的ハイパーテキストを用いて、情報を集めることが出来るので、文書の読み方が劇的に変わった。これを一歩進めて、異なる文書の間又は文書の一部に、新しいリンクを設け、リンクにコメント付けることが出来る。

機械的な方法その他の組合せで、Memexにこれらをさせるのが、Bushの夢だった。今日では、前の章を読むとき頭に浮かぶのは、W. W.W. [3]か又は、90年代中頃のビルゲーツの見通し「指で情報を」だった[4]。Memexは対照的に、情報を機械の中のマイクロフィルムに記憶するが、原理は同じだ。Memexに記憶された情報は、人手又はアルファベット順の検索でない付属検索器を用いまとめてリンクされる。付属検索器を用いるとデータ検索が直観的になる。この際、ハイパーテキストの別の定義が、情報を関連付けて組織する方法[2]となる。脳の中での関連付けが時間と共に又は使う回数と共に希薄になるのに対し、Memexの中の関連付けが長期にわたり威力を発揮する。

ハイパーテキストの両方の定義は、情報の集まりのナビゲーション方法につながっている。だからMemexは、ユーザーが読むのに加えて文書間を飛ぶ経験をさせることの出来るナビゲーション・ハイパーメディアと考えることが出来る。このことは、ハイパーテキストに前の物に加え、情報の非線型組織[2]との、別の定義(前の定義の拡張)を与えることが出来る。

1960年代:Douglas Engelbart とNLS

EngelbartはBushの記事を40年代後半に読んだが、Bushのハイパーテキストの概念を使う世界最初のシステムを開発するまでEngelbartの中で熟するのに15年を要した。NLS(oN-Line System)は(1)アイデアを扱うユーザー(2)各種文書間のリンクの作成(3)通信(4)テキスト処理(5)電子メールの送受信及び(6)ユーザーのシステム構成及びプログラムをサポートした。これは当時聞き慣れないことだった。この機能をユーザーが使い易いように改良するため、システムに当時としては画期的な技術を用いた。中でも、Engelbartは、画面を指してクリックするためマウスに似た品と、ユーザーインターフェイスを常に同じ方法であらわすためのウインドウマネージャとを発明した。ハイパーテキスト部分は、NLS全体の機能の本の一部に過ぎず、主な目的は、地理的に分散しているそれらをうまく共同させるのを助けるツールを提供することであった。今日では、この種のソフトウエアがグループウエアとして多数提案されている。

ユーザーインターフェイスは革命的で、その時代のコンピュータユーザーのレベルから、見て時代を遙かに先取りしていた。前には、ほとんどのプログラマは入力にパンチカード、出力にプリンタを使って間接的にコンピュータとインターフェイスしていた。NLSは全体として、来るべきシステムの予想に役立ち、80年代のAppleのGUI開発を刺激した。

1960年代:Ted NelsonとXanadu

Engelbarと同じく、NelsonもBushの記事[1]に奮起した。しかし、BushやEngelbartと違って、Nelsonは物理学と心理学の基礎があった。60年代始めに、作者が協働して著作、比較、校閲をおこなって著作を電子的に出版することの出来るシステムを想定した。

Xanaduのシステムは何度もリリースされたが、NelsonのXanaduは全く想像の域を出なかった。Xanaduは、それ自体でシステムではなく、別のシステムが守るべきアイデアに過ぎないので、Xanaduとは何かを正確に定義するのは難しい。その名前は、Xanaduの語を何も忘れない文学的記憶の世界[10]を指すのに使ったColeridgeの詩に由来する。実際、Xanaduの背景の考えの一つは、人の知識の大部分が存在する世界docuverseを作ることだった。60年代中頃にハイパーテキストの語を初めて作ったのもNelsonだ。だが彼の定義では、ハイパーテキストとハイパーメディアの両方を含んでいた。

Nelsonのもう一つのアイデアは、集合文書の変更がコピイ側文書にも自動的に伝わることなど、他の文書(又はその一部)を、参照によりコピイしたり、Nelsonのように仮想コピイを作って、参照する特殊な方法であった。この方法で、著者は全体文書著者部分の更新を作成する代わりに料金を請求することができる。このアイデアは、Nelsonの仮想コピイ機構が最初に禁止しようとした領域、著作権問題に物議を醸したが、ある程度今日のディープリンクに似ている。Xamaduプロジェクトからのアイデアの多くは結局w.w.w.及びハイパーメディアシステムにその道を見出すこととなった。

ハイパーメディア・アーキテクチャ

異なる種類のハイパーメディア・システムのアーキテクチャを説明するとき、三つの成分が常に存在する。巨大な一体型から成分ベースのシステムへの革新が起こった理由を良く理解して貰うため、これらの成分と目的を簡単に説明する。早期のハイパーメディア・シテムでも、ユーザーに情報を示す面倒を見るトップのアプリケーション層とともに、古典的な3層モデルを使っている。この層の下にリンク層があり、システムのモデルを仕上げ、管理構造とデータを取り扱う。これは連想と、期間限定の構造である連想をあらわすのに必要な情報である。データは、他方で、文書の実際の内容に関連する。最後に、記憶成分が、システム次第で、構造のみから構造と文書内容双方にわたる範囲の情報の記憶を取り扱う。発達は旋回しながら起こり、新世代毎に、以前にはシステムの核の部分であった機能性を、自分の成分に因数分解した(図参照、枠で囲んだ部分がハイパーメディアシステムの核の部分である成分をあらわす)。説明は一部[5]から取った。

一体型システム

早期のシステムの中の文書構造は、一体型の物であった(図1の左)。分割はユーザーに見えないけれども、3層全部が一つの論理過程にふくまれていた。一体型システムは、アプリケーション・プログラム・インターフェイス(API)も、構造やデータを記憶する方法を記述するプロトコルも公表しない、クローズドシステムと見なされる。これは他のシステムが一体型システムと交信してデータを交換するのを著しく困難にする。システムに記憶された情報の編集などの基本的機能でさえも、僅かなデータフォーマットをサポートするだけの内部アプリケーションが管理した。これは、例えばワープロで作った文章を一体型システムに直接記憶するのを不可能にした。少なくとも、文書内容を内部エディタにコピイしてセーブするまでは駄目だった。

システムがサポートするファイルフォーマットは、開発者が有用と認めたものに限られていた。ワープロで作った文書を引き渡すると、特殊なフォーマット(テキストの一部を太字にする、フォントの変更など)は廃棄された。これはユーザーを悩ませた。ハイパーテキストの機能を利用しようとすると、強力で慣れたアプリケーション環境を諦めてハイパーメディアシステムの内部アプリケーションを使わなければならなかった。ハイパーメディアの設計者は、ハイパーメディア・ソフトウエア開発の専門家だが、ワープロなど別の種類のソフトウエアの専門家ではないので、理想的なソリューションには程遠かった。

引渡問題と共に、システムが関連付けられるデータフォーマットの数が限られていることに関連する問題が生じた。関連する両文書又は両端は、システムの境界内になければならない、つまり、一体型システム内に記憶しなければならない。システムからのデータ取込も不様だ。システムは、包括的ハイパーメディア・システムでサポートすることの稀な自分のフォーマットでデータを記憶するので、取込中にデータが失われるからだ。

これらの欠点はあっても、一体型システムは80年代に広く使われた、その時期に使われたアプリケーションがデータ交換やお互いの交信に神経質でなかったためだろう。一体型ハイパーメディアシステム例は、KMS [2,6]、Intermedia [7]、Notecards [8]及びウインドウズ・ヘルプ・ファイルに使われたマイクロソフト Winhelp システムだ。 厳密に言うと、Winhelp システムその他数多くのヘルプシステムは、在来のハイパーテキストと違う主用途を有するが、兎に角ハイパーメディア機能を使っている。

 
\includegraphics[width=7cm]{arch
図1: 一体型 (左)、クライアント/サーバー(中)、及び
オープン・ハイパーメディア・システム
アーキテクチャ(右)
クライアント/サーバー・システム
一体型システムの説明で多数の欠点を明らかにした。これら問題の幾つかに対する解決策としてユーザーインターフェイス成分システムの核から出してそれ自体の処理に入れた(図1の中央。枠が移って多数のアプリケーションがハイパーメディア・システムにアクセスする)、クライアント/サーバー・ハイパーメディア・システムには二つの味付けが入る。構造、つまり文書間のつながり、に集中するリンク・サーバー・システム(LSS)と、構造と同時に内容にも集中するハイパーベース管理システム(HBMS)だ
ソフトウエアの観点からクライアント/サーバー・ハイパーメディア・システムは、使用するアプリケーションに関するプロトコルとAPIを公開するので感覚としてオープンされている。既存のアプリケーションがユーザーにハイパーメディア機能を提供するものであると、これらのプロトコルとAPIを使う。ハイパーメディアの世界では、しかし、オープンの定義が普通の定義と異なる。アプリケーションに構造とデータの双方を特定するための特殊フォーマットの使用を要求するハイパーメディア・システムは、プロトコルとAPIを公開していても、クローズ・システムと見なされる。オープン・システムとは、対照的に、構造のためのフォーマットを規定するのみである。実際の内容自体に特定のフォーマットを課さないことにより、オープン・システムは、多数の異なるデータフォーマットを扱って、ハイパーメディア・システムの外の各種アプリケーションが作った型とデータの間につながりを作る。
オープンの普通の定義から、W.W.WのHTTPプロトコルは、クライアントのサーバーとの間の多数のメッセージ及び応答を規定する点でオープン・プロトコルである。しかし、構造はHTML文書の中に、構造を規定する多数の hrefその他のタグとして、埋め込まれている。その意味は、href(及びタグ)に関するHTML解析のため特殊アプリケーション(ブラウザ)を必要とすることである。オープンに関するハイパーメディアの定義にしたがうと、W.W.W.がクローズド・ハイパーメディア・システムであるのは、このためである。だから、クライアント/サーバー・システムにおいては、サーバーに記憶された情報を用い、このような方法で、任意の数のアプリケーションが核システムを使用することが出来る。

その他のシステムは、対照的に、文書の相手先に特定のフォーマットを課さない。しかし、それでも、あるAPIを呼び出すためにはアプリケーションのソースコードを変更する必要がある。だから、クライアント/サーバーベース・システムは90年代始めから、アプリケーション成分をハイパーメディア・システムの一体部分としないことにより一体型システムの問題点を解決した。LSSシステムの例はSunのLink Service [9]であるが、W.W.W.は、文書をシステムの一部として、ファイルシステム内のファイルとして記憶するHBHSシステムの例である。

オープン・ハイパーメディア・システム

OHSは、クライアント/サーバー概念の発展なので、OHSとクライアント/サーバー・システムは多数の特徴が共通である。クライアント/サーバー・システムをLSSとHBMSの項に分類出来る場合は、OHSはこれら一つの子孫となる。OHSは、リンク成分だけから成るので(図1の右)、(1)成分はアプリケーションの範囲を超えて使用される機能を含む(2)異なるプラットホームをまたいで働く(3)分散される(4)プロトコルとAPIを公開する、との点から、ミドルウエアと呼ばれることが多い。OHSは、文書の記憶が最早システムの核の一部ではないので、集中記憶がない点で、クライアント/サーバー・システムから区別することが出来る。

データが構造とは別に記憶されるので、テキスト、HTML、グラフィックなどほぼ任意のフォーマットの間のつながりをサポートすることが出来る。アプリケーションが文書関連の構造を必要とするとき、リンクサービスからアプリケーションに送られてデータの適用される。こうして多数のアプリケーションがシステムと会話することが出来る。データ記憶用に特定のプロトコル、つまりW.W.W.上のHTML、使う必要がないからである。詳しく言うと、構造情報は、多数の属性/値の組を含み、多数の属性はデータ型によって変化する。頭で考えると、テキストデータではオフセットが重要なので、座標を規定ればよい。

OHSは、一体型及びクライアント/サーバー・システムが持ち込んだ問題を幾つか解決したが、理想からは遠い。各OHSが独自のプロトコルとAPIを定義するので、すべてのOHSが同じ機能をサポートする訳ではない。LSSシステムの文書は、一般的に既存文書の間で作られた関連付けのみを準備するが、HBMSシステムの文書は、上述のLSS特性に加えて、バージョンや並行制御など内容関連機能もまた含む。その結果は、(1)特定OHSを頭においた書かれたアプリケーションは、別のシステムでは働かない(2)プロトコルとAPIが異なるため、システムを越えて情報を共有することは出来ない(3)最小プロトコルとAPIを規定する共通標準がないため、各システムは自分のAPIを実行して、個々のシステムが互いに連絡することは出来ないようにする、である。さらに、極めて僅かな他のドメインが存在するけれども、ほとんどのOHSは、ナビゲーショナル・ハイパーメディアを頭において設計されている。LSSに由来するOHSの例はMicrocosm [12]で、HBMSに由来するものはHyperform [11]である。

成分ベースのOHS

成分ベースのオープン・ハイパーメディア・システム(CB-OHS)は、「簡単な」オープン・ハイパーメディア・システムに良く似ている。しかし、名前の通り、成分の観念に大きく重点を置く。成分問題の外に、ここで注意すべきことは、この種のシステムが数種の構造領域をサポートし、そのデータを異なる位置に記憶することである。だから、OHSとは主としてリンク成分の点で異なる。

OHSに比べ、第一世代CB-OHS(1G CB-OHS)は、標準の導入により、個々の成分間の協力が掛ける問題を解決しようとした。今の所、ナビゲーショナル・ドメインにけるアプリケーションと構造サービスの連絡方法を規定する合意済み標準があり、追加標準を作成中である。1G CB-OHSのもう一つの目標は、新ドメイン、つまり分類上の又は空間的なドメイン、をサポートする新構造サービス(つまり新成分)の付加によりシステムを拡張して別のドメインもサポートするのを可能にすることである。代わりに、既存成分を改造してOHSを用いる場合のように幾つかのドメインを扱うようにする。CB-OHSに比べると、OHSは構造サービスを一つだけ含む。しかし、既存成分をこのように改造するのは、決して綺麗で融通性のある解決策ではない。然しすべての構造成分に共通なのは、同じAPIを通じて記憶成分にアクセスすることである。この意味は、新構造サービスが自動的に、バージョニング同時制御又は外の何か記憶成分の提供しなければならない「本来の」機構であることだ。

1世代システムがこれらの目標を満足するため、構造サービスは多数のプロトコルとAPIをクライアント(ブラウザ又はハイパーメディア・システムと連絡したい何かのアプリケーション。システムはオープンなハイパーメディア定義に拘泥するので、任意の型のアプリケーションになる)が利用出来るようにする。図2は、それぞれが構造的ドメインをあらわす三つの構造成分を持つアーキテクチャを示す。構造的ドメインはとりわけ、特殊抽象作用、つまりノード、リンク及びナビゲーショナル・ドメインの中の前後関係、抽象作用を扱う。前に述べたように、特殊抽象作用は、各ドメインの中で、既存のものに機能を混ぜるのに代わり、新成分の有力な候補にする。

 
\includegraphics[width=7cm]{arch
図2: A CB-OHS アーキテクチャ

構造成分は記憶成分(ハイパーメディア記憶と言う)と通信するが、その成分は最早単一処理境界内にはないので、通信処理には追加の作業が必要である。ローカル通信は、ある形の処理内通信(IPC)又はローカルプロトコル呼出(LPC)で処理することが出来るが、ネットワークを越えると物事はややこしくなる。ネットワーク間通信をサポートするため、カスタム成分フレームワークに多くの作業が注ぎ込まれた。これがCB-OHSの第一世代と第二世代との間の主な相違でもある。第一世代CB-OHSはカスタムフレームワークを使ったが、第二世代CB-OHSはCOMやCORBAのような一般フレームワークを使う。そこで、開発者はハイパーメディア機能の開発に集中し、低いレベルの通信処理の詳細を無視することが出来る。既存アプリケーション統合に伴う問題は依然として残る。成分フレームワーク使用のため既存アプリケーションを改造するのは、そう簡単でないからだ。

構造成分とアプリケーションとの間のものなど、標準の定義は、オープン・ハイパーメディア・システム・ワーキング・グループ(OHSWG)の努力の結果だ。標準の展開につれ、あらゆるレベルのユーザーの役に立つ[13]。エンドユーザーは、ハイパーメディア機能を今日のあらゆるアプリケーションの内容になっている切り取り、コピイ、貼り付けと同じように考えるようになる[12]。未来のある時期には、「リンク開始」「リンク終了」などのメニュー項目を各アプリケーションに追加するようになり、それらの実行は今日の切り取り、コピイ、貼り付けより少しも難しくなくなるだろう。内容の著作者に取っては、文書と構造がプラットホームとハイパーメディア・システムの境界を越えて再使用出来るので、共通標準が重宝なものになるだろう。最後に、前述の編集機能の他に、開発者は、実際のシステムに関係なく、合意標準に従う限り、標準化システムが提供するものにも集中することが出来るだろう。

まとめ

ハイパーメディア・システムは、常に大きくなる情報の蓄積を、単にアルファベット順に記憶するのよりましな方法で組織する必要のため出現した。Bushが、人の記憶作業の方法に似た機能の機械の考えを述べて以来、人の知識は何千倍にもなり、W.W.W.が多くのハイパーメディア・システムに取って代わって、先駆者の夢を極めて多く実現した。しかし、同時に、W.W.W.が早期の包括的システムに比べ極めて簡単なシステムであることには、何の価値もない。然しこの簡単さ自体が、公衆に対しハイパーメディア機能を浸透させる成功の秘訣だった。

アーキテクチャは、他のすべてのソフトウエアのアーキテクチャと同様に次第に発展した。一体型システムは、他のシステムの経験を認める真剣であり過ぎた。それ以来、物事は大きき変化し、今日のシステムは、各種のフォーマットのデータを受け渡しする。受け渡しのための共通仕様は、SGML又はXMLやHTMLなどの誘導物のようなW3C標準であることが多い。このほかに、各種システムを越えて機構を旨く再使用する能力を、システムに加えよう。

W.W.W.の基本フォーマットであり、今日使用される支配的ハイパーメディア・システムであり、構造とデータの両者をまとめ、W.W.W.がハイパーメディアの感覚ではオープンと認められないHTMLに価値はない。W.W.W.を(成分ベースの)オープンなハイパーメディア・システムに使用との試みが幾つか(成功裡に)なされた。ハイパーメディア領域のすべては、研究中の大きい分野で、この記事で簡単に触れたが、システム及び概念に関する沢山の優れた資料が手に入る。

著作権 (C) 2002年 Ronnie Holm。e-メールで、この記事を使った場所をお知らせ下さい。この記事全部を逐語的に訳して配布することは、この通告を守る限り、どのメディアにも許します。

文献目録

1 Vannevar Bush, As we may think, http://www.ps.uni-sb.de/~duchier/
pub/vbush/vbush.shtml
2  Jeff Conklin, Hypertext: An introduction and survey
3  Tim Berners-Lee et al., The World Wide Web
4  Bill Gates, The Road Ahead
5  Uffe Kock Wiil et al., Evolving hypermedia middleware services: lessons and observations, http://www.cs.aue.auc.dk/~kock/
Publications/Construct/sac99.pdf
6  Robert Akscyn et al., KMS: A distributed hypermedia system for managing knowledge in organisations
7  Nicole Yankelovich et al., Intermedia: The concept and the construction of a seamless information environment
8  Frank Halasz et al., Reflections on Notecards: Seven issues for the next generation of hypermedia systems
9  Amy Pearl, Sun's link service: A protocol for open linking
10 Samuel Taylor Coleridge, Kubla Kahn http://www.geocities.com/chadlupkes/
poetry/xanadu.html
11 Uffe Kock Will et al., Hyperform: Using extensibility to develop dynamic, open and distributed hypermedia systems, http://www.cs.aue.auc.dk/~kock/
Publications/Hyperform/echt92.pdf
12 Hugh Davis et al., Light Hypermedia Link Services: A study of third party application integration
13 Siegfried Reich et al., Addressing interoperability in open hypermedia: The design of the open hypermedia protocol
 
Copyright © 2002, Ronnie Holm.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 78 of Linux Gazette, May 2002
 
 
 
 
PyGTKを用いるアプリケーションの迅速開発

By Krishnakumar R.

競争社会にはアプリケーションを出来るだけ素速く開発するとの決定的先端がある。Python の堅牢性とGTKの素朴な力とを結合した PyGTK を使うとそれが出来る。この記事は、PyGTKを使って科学用電卓を作る指導書だ。

 

1.PyGTKとは?

PyGTK ソース・ディストリビューションから引用しよう。

Well, let me quote from the PyGTK source distribution:



   「このアーカイブには、gtkをPythonプログラムで使うことの出来る


   モジュールが含まれる。現在は、完成した 結合だ。


   バージョン番号は低いが、このソフトウエアは極めて有用で


   複雑さが中位のプログラムを書くのに役立つ」


                                                - README, pygtk-0.6.4


2.何をするか?

pygtkを使って小型科学用電卓を構築する。各段階を詳細に説明する。この処理の段階全部を終えると、pygtkが良く解る。記事の終わりに完成ソースコードへのリンクがある。

3.準備すべきパケージと基本知識

python

このパケージは殆どのLinuxディストリビューションと一緒に入手出来る。私の説明は、Linux RedHat 6.2 マシンに搭載したPython 1.5.2 に基づく python プログラムミングを知らなくとも、心配ない!記事に示された指導に従うだけでよい。

pygtk

このパケージの新しいバージョンは下記から入手することが出来る:

1.ftp://ftp.daa.com.au/pub/james/python
2.ftp://ftp.gtk.org/pub/gtk/python/
3.ftp://ftp.python.org/pub/contrib/Graphics
私の説明はpygtk-0.6.4に基づく。

4.始めよう

この指導書は三つの段階に分かれる。コードとそれに対応する出力を各段階で示す。

5.段階1−ウインドウの構築

先ず、ウインドウを作る必要がある。ウインドウとは容器だ。ボタン、テーブルなどがウインドウに入る。エディタを使ってファイル stage1.py を開く。これに次の行を書き込む:

 



from gtk import *





win = GtkWindow()





def main():


        win.set_usize(300, 350)


        win.connect("destroy", mainquit)


        win.set_title("Scientific Calculator")


        win.show()


        mainloop()





main()


        


1行目は、gtkと言う名のモジュールからメソッドを取り込む。つまり、これでgtkライブラリにあるファンクションを使うことが出来る。

続いて、GtkWindow型のオブジェクト作りwinと名付ける。その後、ウインドウのサイズを設定する。第一引数は幅で、第二引数は高さだ。またウインドウのタイトルも設定する。次ぎに、showの名のメソッドを呼び出す。このメソッドはすべてのオブジェクトの場合に存在する。特定オブジェクトのパラメータを設定した後には、必ずshowを呼び出さなければならない。特定オブジェクトに関するshowを呼び出した後にのみ、ユーザーが見られるようになる。オブジェクトを論理的に作成しても、オブジェクトに関するshowを呼び出さないと、オブジェクトは物理的に見えるようにならない。

ウインドウの信号消去をファンクション mainquit に接続する。mainquit はgtkの内部ファンクションで、これを呼び出すと今走っているアプリケーションを終了することが出来る。信号を気にすることはない。今は、ウインドウを消去するとき(ウインドウ頭の十字印をクリックして)は何時でもmainquit が呼び出されることを理解するだけでよい。つまり、ウインドウズを消去すると、アプリケーションからも離れる。

mainloop() もまたgtkライブラリの内部ファンクションだ。mainloopを呼び出すと、立ち上がったアプリケーションがループの中で、イベントが起こるのを待つ。ここではウインドウが画面上に現れて待つだけだ。 'mainloop' の中で我々の動作を待っている。アプリケーションがループを出るのは、ウインドウを消去してときだけだ。

ファイルをセーブする。エディタを終わってシェルプロンプトに戻る。プロンプトで:

python stage1.py

とタイプする。出力を見るには、Xwindow にいなければならないのを想起されたい。

出力の画面を下記に示す。

stage1.png

 

6.段階2−テーブルとボタンの構築

第二のファイル、stage2.py を 書こう。file stage2.py に次のコードを書く






from gtk import *


 


rows=9


cols=4


 


 


win = GtkWindow()


box = GtkVBox()


table = GtkTable(rows, cols, FALSE)


text = GtkText()


close  = GtkButton("close")


 


button_strings=['hypot(','e',',','clear','log(','log10(','pow(','pi','sinh(','cosh(','tanh(','sqrt(','asin(',


'acos(','atan(','(','sin(','cos(','tan(',')','7','8','9','/','4','5','6','*','1','2','3','-', '0','.','=','+'


]


button = map(lambda i:GtkButton(button_strings[i]), range(rows*cols))


 


 


 


def main():


        win.set_usize(300, 350)


        win.connect("destroy", mainquit)


        win.set_title("Scientific Calculator")


 


        win.add(box)


        box.show()


 


        text.set_editable(FALSE)


        text.set_usize(300,1)


        text.show()


        text.insert_defaults(" ")


        box.pack_start(text)


 


        table.set_row_spacings(5)


        table.set_col_spacings(5)


        table.set_border_width(0)                                                                            





        box.pack_start(table)


        table.show()


 


        for i in range(rows*cols) :


              y,x = divmod(i, cols)


              table.attach(button[i], x,x+1, y,y+1)


              button[i].show()


 


        close.show()


        box.pack_start(close)


 


        win.show()


        mainloop()


 


main()


 

変数 rowscols はそれぞれボタンの行と列を記憶するのに用いられる。新しいオブジェクトのために−テーブル、ボックス、テキストボックス及びボタンを作る。 GtkButton に対する引数は、ボタンのラベルである。だから closeは、"closed" とラベルのついたボタンである。

アレー button_strings は、ボタンのラベルを記憶するのに用いられる。ここでは科学用電卓のキイに現れる記号を用いる。変数 button は、ボタンのアレーだ。mapファンクションがボタンの rows*cols 番号を作る。ボタンのラベルは、アレー button_strings から取る。だから、i番ボタンは button_strings からのi番文字列をラベルとして有する。iの範囲は、0からrows*cols-1までである。

ボックスをウインドウに入れる。このボックスにテーブルを入れる。そのテーブルの中にボタンを入れる。ウインドウ、テーブル及びボタンを倫理的に作った後、それに対応する show を呼び出す。win.add を使って、 box をウインドウに加える。

text.set_editable(FALSE) を使って、テキストボックスを編集不能にする。これはタイプしてテキストボックスに外から何かを加えることは出来ないことを意味する。text.set_usize は、テキストボックスのサイズを設定し、text.insert_defaults は、空白文字列を規定値としてテキストボックスに挿入する。このテキストボックスを box の始めに詰め込む。

テキストボックスの後でテーブルをボックスに挿入する。テーブルの引数設定は平凡だ。forループで四つのボタンを9行に入れる。ステートメント y,x = divmod(i, cols) は、iの値を cols で割って、商をyに剰余をxに記憶する。

最後に close ボタンをボックスに入れる。pack_start がオブジェクトを、ボックス内で利用出来る次の自由空間に入れることを想起されたい。

ファイルをセーブして

python stage2.py

とタイプする。出力の画面を下記に示す。

stage2.png

 

7.段階3−電卓用バックグラウンドの構築

アプリケーションに電卓の作用をさせるため、幾つかのファンクションを書かなければならない。このファンクションをバックグラウンドと言う。これらは、scical.py にタイプする行である。これが最後の段階だ。scical.py は、完成出力を含む。プログラムを書きに示す:

 



from gtk import *


from math import *


 


toeval=' '


rows=9


cols=4


 


win = GtkWindow()


box = GtkVBox()


table = GtkTable(rows, cols, FALSE)


text = GtkText()


close  = GtkButton("close")


 


button_strings=['hypot(','e',',','clear','log(','log10(','pow(','pi','sinh(','cosh(','tanh(','sqrt(','asin(','acos(','atan(','(','sin(','cos(','tan(',')','7','8','9','/','4','5','6','*','1','2','3','-', '0','.','=','+']


button = map(lambda i:GtkButton(button_strings[i]), range(rows*cols))





def myeval(*args):


        global toeval


        try   :


                b=str(eval(toeval))


        except:


                b= "error"


                toeval=''


        else  : toeval=b                                    


        text.backward_delete(text.get_point())


        text.insert_defaults(b)











def mydel(*args):


        global toeval


        text.backward_delete(text.get_point())


        toeval=''


 


def calcclose(*args):


        global toeval


        myeval()


        win.destroy()


 


def print_string(args,i):


        global toeval


        text.backward_delete(text.get_point())


        text.backward_delete(len(toeval))


        toeval=toeval+button_strings[i]


        text.insert_defaults(toeval)


 


 


def main():


        win.set_usize(300, 350)


        win.connect("destroy", mainquit)


        win.set_title("Scientific Calculator: scical (C) 2002 Krishnakumar.R, Share Under GPL.")


 


        win.add(box)


        box.show()


 


        text.set_editable(FALSE)                       


        text.set_usize(300,1)


        text.show()


        text.insert_defaults(" ")


        box.pack_start(text)


 


        table.set_row_spacings(5)


        table.set_col_spacings(5)


        table.set_border_width(0)


        box.pack_start(table)


        table.show()


 


        for i in range(rows*cols) :


              if i==(rows*cols-2) : button[i].connect("clicked",myeval)


              elif  (i==(cols-1)) : button[i].connect("clicked",mydel)


              else                : button[i].connect("clicked",print_string,i)


              y,x = divmod(i, 4)


              table.attach(button[i], x,x+1, y,y+1)


              button[i].show()


 


        close.show()


        close.connect("clicked",calcclose)


        box.pack_start(close)


 


        win.show()


        mainloop()


 


main()                                              




 




新変数 toeval を導入した。この変数は、計算すべき文字列を記憶する。計算すべき文字列は一番上のテキストボックスに存在する。= ボタンを押したときこの文字列を計算する。これはファンクション myeval を呼び出しておこなう。Pytohonファンクション eval を文字列内容を計算し、結果をテキストボックスにプリントする。文字列の計算が(構文エラーなどで)出来ないときは、文字列を 'error' プリントする。この処理のため try exceptを用る。




clear、 close 及び = 以外のその他のボタンを押すと、ファンクション print_string がトリガされる。このファンクションは、先ずテキストボックスをクリアする。押されたボタンに対応する文字列を、変数 toeval に付加して toeval をテキストボックスに表示する。


ここで close ボタンを押すと、ファンクション calcclose が呼び出され、これがウインドウを壊す。clear ボタンを押すと、ファンクション mydel が呼び出され、テキストボックスがクリアされる。ファンクション main では、for ループに三つのステートメントを加えた。これらは、対応するファンクションをボタンに割り当てるためのものである。 = ボタンを myevalファンクションに付属させ、 clear mydel に付属させるなどである。

こうして、完全な科学用電卓が使えるようになった。シェルプロンプトで scical.py とタイプするだけで、科学用電卓が働く。

最終アプリケーションの絵を下に示す。

scical.png

 

8.まとめ

各段のコードは下記のリンクをクリックするとダウンロードすることが出来る。

1.stage1.py
2.stage2.py
3.scical.py

これらはすべて .txt .txt 拡張子を有する。この拡張子を除去してプログラムを走らせる。例えば、実行前に stage1.py.txt を stage1.py に変更する。

pygtk パケージについて来る examples ディレクトリには沢山の例がある。これらは、Linux, RehHat 6.2 では、/usr/doc/pygtk-0.6.4/examples/ ディレクトリの下で見付かる。これらのプログラムを走らせて、そのソースコードを読む。それは、複雑なアプリケーションの開発に大いに役立つであろう。

 

Krishnakumar R.(著者紹介)

Krishnakumar は Govt. Engg. College Thrissur, Kerala, India の B.技術学生 最終学年だ。OSの世界への旅はLinuxのモジュールプログラムから始まった。彼は GROS.(詳細は彼のホームペイジ: http://www.askus.way.to/ )と言う名のルーティングOSを構築した。 ネットワーク、デバイスドライバ、コンパイラ移植、埋込システムにも興味を持っている。
Copyright © 2002, Krishnakumar R..
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 78 of Linux Gazette, May 2002
 
 
 
 
QTライブラリを用いる
C++によるGUIプログラミング、パートI

By Gaurav Taneja

GUI開発ライブラリの広大な世界の中に、超然として、Trolltech ASの開発したC++用 'Qt' がある。 'Qt' は1996年に紹介されて以来、このライブラリを使って各種アプリケーション用に優れたインターフェイスが開発された。

Qtは、クロスプラットホームで、MS/Windows,Unix/X11 (Linux, Sun Solaris, HP-UX, Digital Unix, IBM AIX, SGI IRIX and many other flavors),Macintosh ( Mac OS X ) 及び Embedded プラットホームをサポートする。これとは別に、'Qt' はオブジェクト指向、コンポーネントベース、プログラマの選択に任された多数のウィジェットを有する。'Qt' は「Qtプロフェッショナル」と「Qtエンタープライズ」と両方のバージョンで商業的に入手することが出来る。無料版はQtの非売バージョンで(http://www.trolltech.com/).からダウンロードすることが出来る。

開始

先ずライブラリをダウンロードする。これから取り上げる例ではLinux用Qt/X11バージョンをダウンロードしたと、仮定する。

インストールするにはスーパーユーザー特権が必要なので、'root'.にいることを確認する。

/usr/local ディレクトリにuntarする:

[root@Linux local]# tar -zxvf qt-x11-free-3.0.1

[root@Linux local]# cd qt-x11-free-3.0.1

次ぎに、使用に必要なオプションを付けてライブラリをコンパイルしインストールする。'Qt' ライブラリは、必要に合った特注オプションを付けてコンパイルすることが出来る。基本特性とは別に、gif読取、スレディング、STL、リモートコントロール、Xinerama、XftFreeタイプ及びXセッション管理をコンパイルする。

前に進む前に、正しい位置をポイントする環境変数を次のように設定するの忘れないこと:

QTDIR=/usr/local/qt-x11-free-3.0.1
PATH=$QTDIR/bin:$PATH
MANPATH=$QTDIR/man:$MANPATH
LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH

export QTDIR PATH MANPATH LD_LIBRARY_PATH

この情報を、ホームディレクトリにある .profile に含むことが出来る。

[root@Linux qt-x11-free-3.0.1]# ./configure -qt-gif -thread -stl -remote -xinerama -xft -sm

[root@Linux qt-x11-free-3.0.1]# make install

すべて旨く行ったら、 'Qt' ライブラリがインストールされた。

'Qt' を用いる第一ステップ

'Qt'ライブラリを用いてC++でプログラムを書くには、仕事を容易にするため、'Qt'ライブラリで利用出来る重要なツールとユティリティを理解しなければならない

Qmake

Qmake は、'.pro' ファイルに基づく情報を用いて makefiles するのに用いる。

簡単なプロジェクトファイルの見掛けは次のようだ:



    SOURCES = hello.cpp


    HEADERS = hello.h


    CONFIG += qt warn_on release


    TARGET  = hello


ここで、'SOURCES' はアプリケーション用実行ソース全部を定義するのに使うことが出来る。一つ以上のソースファイルがあるときは次のように定義する:

SOURCES = hello.cpp newone.cpp



又は代わりに次のようにする:


    SOURCES += hello.cpp


    SOURCES += newone.cpp


同様に'HEADERS'はソースに所属するヘッダファイルを規定するのに用いる。'CONFIG' 部分はアプリケーション構成に付いての情報をqmakeに渡すのに便利である。このプロジェクトファイルの名は、アプリケーションの実行可能プログラムと同一でなければならない。今の場合は 'hello.pro' である。.

Makefile は、次のコマンドを送って作成する:



[root@Linux mydirectory]# qmake -o Makefile hello.pro 




Qt Designer




Qt Designer は、'Qt' ライブラリを用いてユーザーインターフェイスを視覚的に設計しコードするのに用いる。WYSIWYGインターフェイスは、ユーザーインターフェイスを微調整し、各種ウィジェットを用いて実験するためにある。このデザイナは、CUI用のソース全体をさらに強化するため何時でも作成する能力がある。 'Qt Designer' の詳細は一緒に来る資料で調べること。




Hello World!




基本的 'Hello World' プログラムの理解から始めよう。任意のソースエディタを用いて次のコードを書く:


#include <qapplication.h>
#include <qpushbutton.h>

int main( int argc, char **argv )
{

QApplication a( argc, argv );
QPushButton hello( "Hello world!", 0 );
hello.resize( 100, 30 );
a.setMainWidget( &hello );
hello.show();
return a.exec();

}

このコードを平文ファイル('hello.cpp')としてセーブする。このコードを、次のようにproject file (.pro)を作ってコンパイルする:

TEMPLATE = app
CONFIG += qt warn_on release
HEADERS =
SOURCES = hello.cpp
TARGET = hello

このファイルを 'hello.pro' としてソースファイルと同じディレクトリにセーブし、Makefile の作成を続ける。



[root@Linux mydirectory]# qmake -o Makefile hello.pro


Compile it using 'make'



[root@Linux mydirectory]# make





これで初めての'Qt' をテストする準備が出来た。'X' にいることを条件に、プログラムを実行可能に立ち上げることが出来る





[root@Linux mydirectory]# ./hello





次のようなものが現れる筈だ:







Snapshot













 




書き上げたコードのそれぞれを理解しよう





最初の2行には、QApplication とQPushButton クラスの定義が含まれる。


アプリケーション全体に QApplication オブジェクト一つだけがなければならないことを常に忘れないこと。





他のC++プログラムと同じく、main() ファンクションはプログラムへのエントリポイントで、argc はコマンド行引数、 argv はコマンド行引数のアレーである。





次ぎにこれらQt の受け取った引数を下のように渡す。





QApplication a(argc, argv)





次ぎにQPushButton オブジェクトを作り、二つの引数、ボタンのラベルと親ウインドウ(0 、つまりこの場合は自分自身のウインドウ)、を用いてそのコンストラクタを初期化する。





次のコードを用いてボタンのサイズを変える:





hello.resize(100,30);





Qt アプリケーションは、任意選択で、それに関連するmain widgetを持つことが出来る。main widgetを閉じると、アプリケーションが終わる。





main widgetを次のように設定する:





a.setMainWidget( &hello );





次ぎに main widget が見えるように設定する。見えるようにするには常に show() を呼び出さなければならない。





hello.show();





次ぎに、制御を最終的にQt  にわたす。ここで忘れてはならない重要点は、アプリケーションが生きて、アプリケーションの存在を返答するまでexec()が走り続けることである。





Gaurav Taneja (著者自己紹介)

Iインドのニューデリーで、 Linux/Java/XML/C++ の技術コンサルタントとして働いている。オープンソースプロジェクトに積極的に参加している。趣味は、ドライブ、テニス、映画鑑賞、パーテーだ。自分のソフトウエア会社 BroadStrike Technologies.も経営したいる。
Copyright © 2002, Gaurav Taneja.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 78 of Linux Gazette, May 2002
 
  
 
C++によるXlibプログラミング

By Rob Tougher

1. 緒言
2. ウィジェットセットを使わなかった理由
3. 基本
3.1 ディスプレーを開く
3.2 ウインドウを作る
3.3 イベントを取り扱う
3.4 描画する
4. 上級 - スクラッチからコマンドボタンを作る
4.1 ボタンの要件
4.2 それ自体のウインドウを与える
4.3 "pressed" と"not pressed" ドロー状態の実行
4.4 どちらの状態に引き込むか考える
4.5 "text" プロパティを与える
4.6 "on_click()" イベントを発生させる
5. 結語
a. 参考資料
b. ファイル
 
1. 緒言
任意のローカル又はリモートのXサーバーの画面に、C言語を用いてグラフィックスを描くことの出来るXlibはライブラリである。それに必要なことは、 <X11/Xlib.h>をインクルードすること、-lX11スイッチを用いてプログラムをリンクすることで、これによりこのライブラリのあらゆる機能を使う準備が終わる。.

例えば、ローカルマシンにウインドウを作って示したいとすると、次のように書くことが出来る:

リスト 1: example1.cpp



#include <X11/Xlib.h>


#include <unistd.h>





main()


{


  // ディスプレーを開く


  Display *d = XOpenDisplay(0);





  if ( d )


    {


      // ウインドウを作る


      Window w = XCreateWindow(d, DefaultRootWindow(d), 0, 0, 200,


                   100, 0, CopyFromParent, CopyFromParent,


                   CopyFromParent, 0, 0);





      // ウインドウを示す


      XMapWindow(d, w);


      XFlush(d);





      // ウインドウを見るに十分なだけスリープ


      sleep(10);


    }


  return 0;


}


次のコマンドでプログラムをコンパイルすることが出来る:



prompt$ g++ test.cpp -L/usr/X11R6/lib -lX11


prompt$ ./a.out


すると画面に次のウインドウが10秒間現れる:

この記事の目的は、Xlibアプリケーションを開発するとき使用することの出来る簡単なクラスを示すことにある。ボタンが一つ付いたウインドウを持つアプリケーション例を作る。そのボタンは、Xlibライブラリだけを用いて開発するカスタムボタンである。

2. ウィジェットセットを使わなかった理由

QTGTKのようなウィジェットライブラリを使っては?」と自問自答されるだろう。尤もな疑問だ。私はQTを束区、Linuxプラットホーム用を目標にC++アプリケーションを開発するとき、極めて役に立つと思う。

これらのクラスを開発した理由は、Xウインドウシステムを良く理解するためだ。それにはQTやGTKなどの覆いの下で何が行われているかを理解せざるを得なかった。仕上げたとき、私の作ったクラスが実際に役立つことが解った。

だから、この記事から学んで、自分のアプリケーションに活用して頂きたい。

3. 基本

コードに入ろう。この章ではXlibの基本的特徴を検討する。

3.1 ディスプレーを開く

最初に作ったクラスは、ディスプレーの開閉を担当する display クラスだ。example1.cppで、ディスプレー・プロパティをXCloseDisplay()で閉じなかったのに気付かれただろう。このクラスを用いて、プログラムを出る前に閉じられる。我々の例は次の通りだ:

リスト2: example2.cpp



#include <unistd.h>





#include "xlib++/display.hpp"


using namespace xlib;





main()


{


  try


    {


      // ディスプレーを開く


      display d("");





      //ウインドウを作る


      Window w = XCreateWindow((Display*)d,


                   DefaultRootWindow((Display*)d),


                   0, 0, 200, 100, 0, CopyFromParent,


                   CopyFromParent, CopyFromParent, 0, 0);





      // ウインドウを示す


      XMapWindow(d, w);


      XFlush(d);





      // ウインドウを見るに十分なだけスリープ


      sleep(10);


    }


  catch ( open_display_exception& e )


    {


      std::cout << "Exception: " << e.what() << "\n";


    }


  return 0;


}


華々しいことは何もない、ディスプレーを開いて閉じただけだ。 implementation で、display くらすがDisplay*演算子を定義するのに気付かれるだろう。しなければならないのは、オブジェクトを実際のXlibディスプレー・ポインタを得るようキャストしすることだ。

try/catch にも注意のこと。この記事のクラスは全部信号エラー状態に対しカスタム除外を入れる。

3.2 ウインドウを作る

次ぎにしたいのはウインドウ作成を簡単にすることだ。そこで、mixに window クラスを加えた。このクラスは、コンストラクタの中にウインドウを作って示し、デストラクタでそのウインドウを壊す。我々の例は、次のようになる(event_dispatcherに注意、次ぎにこの問題に移る):

リスト3 : example3.cpp



#include "xlib++/display.hpp"


#include "xlib++/window.hpp"


using namespace xlib;





class main_window : public window


{


 public:


  main_window ( event_dispatcher& e ) : window ( e ) {};


  ~main_window(){};


};





main()


{


  try


    {


      // Open a display.


      display d("");





      event_dispatcher events ( d );


      main_window w ( events ); // top-level


      events.run();


    }


  catch ( exception_with_text& e )


    {


      std::cout << "Exception: " << e.what() << "\n";


    }


  return 0;


}


main_window クラスが xlib::window の引き継ぎであることに注意。 main_window オブジェクトを作るとき、実際のXlibウインドウを作るベースclass' コンストラクタが呼び出される。

3.3 イベントを取り扱う

最後の例にある event_dispatcher クラスに気付かれただろう。このクラスはアプリケーションの待ち行列からイベント取り外して、正しいウインドウに送る。

このクラスは次のように定義される:

リスト4 : event_dispatcher.hpp



      class event_dispatcher


    {


      // constructor, destructor, and others...


      [snip...]





      register_window ( window_base *p );


      unregister_window ( window_base *p );


      run();


      stop();


      handle_event ( event );


    }


event_dispatcher は、イベントをwindow_base インターフェイスを介してwindowクラスに渡す。この記事の中のwindewをあらわすクラスはすべて、このクラスから導かれ、送り主からのメッセージを受け取ることが出来る。これらがregister_window を用いてレジスタされると、メッセージの受信を始める。 window_base は次のように宣言され、これらから導かれるクラスはすべてこれらのメソッドを定義しなければならない。

 

リスト5 : window_base.hpp



      virtual void on_expose() = 0;





      virtual void on_show() = 0;


      virtual void on_hide() = 0;





      virtual void on_left_button_down ( int x, int y ) = 0;


      virtual void on_right_button_down ( int x, int y ) = 0;





      virtual void on_left_button_up ( int x, int y ) = 0;


      virtual void on_right_button_up ( int x, int y ) = 0;





      virtual void on_mouse_enter ( int x, int y ) = 0;


      virtual void on_mouse_exit ( int x, int y ) = 0;


      virtual void on_mouse_move ( int x, int y ) = 0;





      virtual void on_got_focus() = 0;


      virtual void on_lost_focus() = 0;





      virtual void on_key_press ( character c ) = 0;


      virtual void on_key_release ( character c ) = 0;





      virtual void on_create() = 0;


      virtual void on_destroy() = 0;


これが実際に働くかを見よう。ウインドウでButtonPress イベントを扱う。main_window classに次のコードを加える:

リスト6 : example4.cpp



class main_window : public window


{


 public:


  main_window ( event_dispatcher& e ) : window ( e ) {};


  ~main_window(){};





  void on_left_button_down ( int x, int y )


  {


    std::cout << "on_left_button_down()\n";


  }





};


コードをコンパイルして例を走らせ、ウインドウの中をクリックする。働く! event_dispatcherがButtonPress メッセージを受け取って、あらかじめ定義した on_left_button_down メソッドを経由してウインドウに送る。

3.4 描画する

次ぎにウインドウに描画する。Xウインドウシステムは、引き込む"graphics context" の概念をていぎするので、当然我々も graphics_context.と言う名のクラスを作った。以下がクラスの定義だ:

リスト 7 : graphics_context.hpp



  class graphics_context


    {


    public:


      graphics_context ( display& d, int window_id );


      ~graphics_context();





      void draw_line ( line l );


      void draw_rectangle ( rectangle rect );


      void draw_text ( point origin, std::string text );


      void fill_rectangle ( rectangle rect );


      void set_foreground ( color& c );


      void set_background ( color& c );


      rectangle get_text_rect ( std::string text );


      std::vector get_character_widths ( std::string text );


      int get_text_height ();


      long id();





    private:





      display& m_display;


      int m_window_id;


      GC m_gc;


    };


このクラスにウインドウidと、display オブジェクトを渡すと、drawing メソッドを使って好きなことを描くことが出来る。試して見よう。我々の例に次を付け加える:

リスト8 : example5.cpp



#include "xlib++/display.hpp"


#include "xlib++/window.hpp"


#include "xlib++/graphics_context.hpp"


using namespace xlib;





class main_window : public window


{


 public:


  main_window ( event_dispatcher& e ) : window ( e ) {};


  ~main_window(){};





  void on_expose ()


  {


    graphics_context gc ( get_display(),


           id() );





    gc.draw_line ( line ( point(0,0), point(50,50) ) );


    gc.draw_text ( point(0, 70), "I'm drawing!!" );


  }





};


on_expose() メソッドは、ウインドウが表示、つまりexposeされたとき何時でも呼び出される。このメソッドでは、ウインドウのクライアント領域に直線とテキストを描く。この例をコンパイルして走らせると、以下のような画面が現れる筈だ:

graphics_context クラスは、この記事の後の方で何度も使う。

上のコードに helper クラス、point and line、があるのに気付かれただろう。これらは私の作った小さいクラスで、すべて形状に関する。今は必要ない用に思えるが、後で変形などの複雑な操作をおこなうとき役立つ。例えば、."line_x += 5; line_y += 5;"と命じるより、"line.move_x(5)"と命じる方が楽で、エラーも起こり難い。

 

4. 上級 - スクラッチからコマンドボタンを作る

4.1 ボタンの要件

簡単な材料が揃ったので、再使用出来る実際のウィジェット作成に移ろう。アプリケーションで使用することの出来るコマンドボタンの作成に集中する。このボタンの要件は次の通りだ:

・イベントを受け取る自分自身のウインドウを持つこと
・二つのドロー状態 - "pressed" と "not pressed" - を持つこと
・マウスボタンをコントロールの枠の中で押し、コントロールの上に静止させたとき、"pressed" 状態を引き出すこと
・マウスボタンを押さないか、又は押してもマウスがコントロールの枠の外にあるとき、"not pressed" 状態を引き出すこと
・クライアントに "on_click()" イベントを送ることが出来ること

これらは簡単なコントロールのように思えるが、これら全部が意味することは些細なことではない。以下の節で説明する。

4.2 それ自体のウインドウを与える

先ず、このコマンドボタンに別のウインドウを作らなければならない。コンストラクタがshow メソッドを呼び出し、これが create メソッドを呼び出し、これがウインドウ作成をおこなう:

リスト9 : command_button.hpp



      virtual void create()


    {


      if ( m_window ) return;


      m_window = XCreateSimpleWindow ( m_display, m_parent.id(),


                       m_rect.origin().x(),


                       m_rect.origin().y(),


                       m_rect.width(),


                       m_rect.height(),


                       0, WhitePixel((void*)m_display,0),


                       WhitePixel((void*)m_display,0));


      if ( m_window == 0 )


        {


          throw create_button_exception 


        ( "could not create the command button" );


        }





      m_parent.get_event_dispatcher().register_window ( this );


      set_background ( m_background );


    }


window クラスのコンストラクタに大変良く似ている。Xlib API XCreateSimpleWindow()を用いて先ずウインドウを作り、続いて, event_dispatcher に自分を登録してイベントを自分で受け取るようにし、最後にバックグラウンドを設定する。

XCreateSimpleWindow()に対する呼出の中に親ウインドウのidを渡すのに注意。Xlibに我々のコマンドボタンが親ウインドウの子ウインドウであることを告げている。

 

4.3 "pressed" と"not pressed" ドロー状態の実行

コマンドボタンはevent_dispatcher に自分を登録したので、自分を引き出す必要があるとき on_expose()イベントを受け取る。両状態を引き出すのに、我々はgraphics_context クラスを用いる:

以下は、"not pressed" 状態のために使うコードである:

リスト10 : command_button.hpp



      // bottom


      gc.draw_line ( line ( point(0,


                  rect.height()-1),


                point(rect.width()-1,


                  rect.height()-1) ) );


      // right


      gc.draw_line ( line ( point ( rect.width()-1,


                    0 ),


                point ( rect.width()-1,


                    rect.height()-1 ) ) );





      gc.set_foreground ( white );





      // top


      gc.draw_line ( line ( point ( 0,0 ),


                point ( rect.width()-2, 0 ) ) );


      // left


      gc.draw_line ( line ( point ( 0,0 ),


                point ( 0, rect.height()-2 ) ) );





      gc.set_foreground ( gray );





      // bottom


      gc.draw_line ( line ( point ( 1, rect.height()-2 ),


                point(rect.width()-2,rect.height()-2) ) );


      // right


      gc.draw_line ( line ( point ( rect.width()-2, 1 ), 


                point(rect.width()-2,rect.height()-2) ) );


後で、最終的にこのコードをコンパイルすると、ボタンは次のような見掛けになる:

代わりに、ボタンを押すときは、それを引き出すのに次のコードを用いる:

リスト11 : command_button.hpp



      gc.set_foreground ( white );





      // bottom


      gc.draw_line ( line ( point(1,rect.height()-1),


                point(rect.width()-1,rect.height()-1) ) );


      // right


      gc.draw_line ( line ( point ( rect.width()-1, 1 ),


                point ( rect.width()-1, rect.height()-1 ) ) );





      gc.set_foreground ( black );





      // top


      gc.draw_line ( line ( point ( 0,0 ),


                point ( rect.width()-1, 0 ) ) );


      // left


      gc.draw_line ( line ( point ( 0,0 ),


                point ( 0, rect.height()-1 ) ) );





      gc.set_foreground ( gray );





      // top


      gc.draw_line ( line ( point ( 1, 1 ),


                point(rect.width()-2,1) ) );


      // left


      gc.draw_line ( line ( point ( 1, 1 ),


                point( 1, rect.height()-2 ) ) );


完成すると次のような見掛けになる:

4.4 どちらの状態に引き込むか考える

これは極めて簡単な問題のように思える−コントロールの上でマウスを押したとき"pressed"を、上がっているとき"not pressed" 状態を呼び出す−だけだ。だが、これは正しくない。コントロールの上でマウス左ボタンを押したままにして枠の外に動かすと、今マウス左ボタンが押されていても、コマンドボタンは "not pressed" 状態を引き出す。

command_button クラスは、これを扱うのに、二つのメンバー変数−m_is_downm_is_mouse_over−変数を用いる。最初、コントロールの上でマウスを押したとき ( on_left_button_down()参照), down 状態にしてコントロールをリフレッシュする。その結果、コマンドボタンは自分をpressed状態に引き込む。何時か、マウスがコントロールの枠の外に動くと(on_mouse_exit()参照), m_is_mouse_over が偽に設定され、コントロールがリフレッシュされる。その結果、コマンドボタンは自分を "not pressed" 状態に引き込む。このとき、マウスがコントロールの枠の中に動くと、m_is_mouse_over が真に戻って、コントロールはpressに引き込まれる。マウスボタンを解放されると、自分を"not pressed" 状態に設定して、自分をリフレッシュする。

 

4.5 "text" プロパティを与える

これは極めて簡単な問題だ。このコマンドボタンを使う人がテキストを得て表示出来るようにする。コードを示す:

リスト12 : command_button.hpp



      std::string get_name() { return m_name; }


      void set_name ( std::string s ) { m_name = s; refresh(); }


refresh() は、コントロール自体に新しいテキストを書かせるためここに置いた。

4.6 "on_click()" イベントを発生させる

このコマンドボタンを使う人が、何処をクリックしたか判るようにする。そのため、"on_click()"イベントを作る。以下が command_button_baseクラスの定義だ:

リスト 13 : command_button_base.hpp



namespace xlib


{


  class command_button_base : public window_base


    {


    public:


      virtual void on_click () = 0;


    };


};


ここで基本的に言っていることは「ウインドウの行うイベントすべてに加えてもう一つ on_click()をサポートする」ということだ。このボタンを使う人は、これから新しいクラスを導き出し、 on_click() クラスを実行して、適切な動作をさせることが出来る。

5. 結語

この記事がお役に立てば幸いだ。Xlibの色々な特性を説明し、C++クラスにまとめて、sjぴらおmpXlib開発を容易にした。この記事又はXlib開発一般に付いての質問、ご意見、ご教示がe-メールされたい email me.

a. 参考資料
http://www.xfree86.org/- XFree86のホームペイジ、X Window System に関するオープンソース情報
Xlib Programming Manual- Xlib 開発に関する大きい情報源
The X Protocol - www.x.orgからのXプロトコルについての情報
b. ファイル
・例
Makefile - 例の全部をコンパイルする
Example1 - Xlibを用いて簡単なウインドウを作る
Example2 - displayクラスを使う
Example3 - window クラスを使う
Example4 - event_dispatcher を用いるイベント取扱い
Example5 - graphics_context クラスを用いて直線とテキストを描く
Example6 - 動作中の完成コマンドボタン
・xlib++ クラス
shapes.hpp - 各種shapeクラスを含む
character.hpp, color.hpp - 雑ヘルパー
command_button_base.hpp - command_button_base アブストラクトクラス
command_button.hpp - command_button クラス
event_dispatcher.hpp -イベント取扱い用 event_dispatcher クラス
display.hpp - display クラス
exceptions.hpp - 各種カスタム表現クラス
graphics_context.hpp - 描画用graphics_context クラス
window_base.hpp - window_base アブストラクトクラス
window.hpp