TSG 部報 第 191 号・夏合宿前号


[-> TSG Home Page]


夏合宿のお知らせ

小島 司

 今年の夏合宿は, 以下の様に企画しております.

行先 : 伊豆大島
費用 : 25000 円
内訳 :
船運賃・宿泊費 (2 泊 4 食付き)・花火代・28 日朝食代・コンパ代
宿泊 :
野田浜園 tel xxxxx-x-xxxx
海水浴場まで徒歩 5 分, テニスコートまで同 1 分, 各室 TV あり
旅程 :
7 月 27 日 (木) 夜 8 時 30 分, JR 浜松町駅北口 (大門通り沿 い) 集合, 竹芝桟橋より出発
28 日 (金) 朝 5 時, 大島着, 大島泊
29 日 (土) 大島泊
30 日 (日) 午後 1 時 10 分, 大島を出発 竹芝桟橋到着は夕方 5 時 30 分
 宿の環境は良い様ですので, 充実した休暇を過して頂ける事と思います. 現 在, 参加のお返事は以下の様に頂いています. (敬称略)

参加決定 :
綾塚, 今西, 岡村, 小島, 沢田, 三瓶 (29 日午後より), 須磨, 多賀, 寺川, 中村 (成貴), 西澤, 西本, 畠山, 松浦 (健一郎), 森川, 安田, 渡辺 (尚)
予定が合えば参加する :
安島, 小林, 崎山, 原田, 牧野, 光田 (新入生), 岡崎, 片岡, 金子, 桜井, 高野, 寺田, 野村, 松村

 参加の受付の最終締切りは 7 月 10 日とします. 多くの方のご参加をお待 ちしております.

★テニスをなさる方は, おっしゃって下さい. 靴以外は, レンタル可能で す.

★また, 参加なさる方は, 7 月 30 日に有効な学割証が必要になります. 7 月 10 日までに小島, もしくは西本さんに手渡しなさるか, 根津研の“電話代専 用”と書いてある箱に入れて置いて下さい.
 7 月 10 日の夜 8 時頃に根津研に取りに行きます.

小島 司
tel xx-xxxx-xxxx
g441036@komaba.ecc.u-tokyo.ac.jp
QZD03022@niftyserve.or.jp
sigma@いぬ。BBS
sigma.tsg@ICCC


ウイルスについて

TEA

 みなさんよくご存知でしょうけど, 部室でウイルスが発見されました.

 というのは TSG Vol.166*1 のぼくの記事の書き出 しですが, 今年も 5 月 13 日にウイルスが発見されました. その日はちょう ど新歓コンパの日だったので, ぼくはトレードをあさろうかとかなり早い時間 に部室に来ました. GR の電源をいれて, 起動するまで部誌の新しいほうから 見てみたら, ATOK がハングするとかそういうことが書いてあって, またかと か思いながら(笑), GR のハードディスクに自分のディレクトリを作りました. それから, ksh がなかったのでどういうソフトが入っているのかなあとながめ ていたら, LHE があって, おおとか思ったのですが, どうもファイルサイズが 変なのです(笑). 9613 バイトあるんです. ぼくは, 確か 8000 バイトなかっ たはずだよなあとか思いながら, FD の viewer でファイルの中身をながめて いました. でもなんか変なのです(笑). それでもまだ気づかなくて, こばんざ めのようなソフトがあるのかと思いました. (^^; 30 秒だか 1 分たって, ATOK がハングすると部誌に書いてあったのを思い出して, そうかウイルスか と気づきました. (^^;

 最初は部室でプログラムを作ろうかとも思っていたのですが, おかげででき なくなりました. だって, 5 月 17 日にプログラムを公開しようとしていたの で, うちに感染するのがこわかったからです. (^^; しかたないので, そのウ イルスがどういうものかとか, どのくらい感染しているのかとか調べることに しました. 最近の DOS にはウイルスを探すソフトが確かついてくるんだよな あと思って DOS のディレクトリを探したのですがどれだか分かりませんでし た. あとでわかったのですが, Virus Buster の略で VB なんとかというのが それだったみたいですね. ぼくはそれは Visual Basic だと思って使いません でした. (^^;

 そのウイルスに感染しているプログラムは, 最初のほうと最後に MsDos と いう文字列が入るようなので, grep でさがしたらうじゃうじゃ感染していま した. 前回と違って今回は COM だけでなく EXE にも感染するようです. おか げで Windows が起動しなくなりました. あと, プログラムを起動していたら 感染が広がるじゃないかと言われそうですが, ワクチンがあればそれでいいし, なければどうせフォーマットするので好きなことしています. (^^; 次に, ど うやって感染するのかをしらべようと思って symdeb でトレースしようと思っ たのですが, MS-DOS のファンクションリクエストを拡張して, 感染の動作は 常駐部がやっているみたいだったので, あきらめました. 感染したプログラム は持って帰ろうと思ったんですが, ぼくはおおぼけなので自分の家が感染した ら困るのでやめておきました. (^^;

 で, いつどこから感染したかですが, 前日の金曜日に感染したみたいで す. その日の午後から Windows が起動しなくなったみたいですから. どこか ら感染したかはまたわからなかったみたいですが, 新学期になるとどこからか やってくるみたいですね.

▼被害にあった PC-486GR

「ウイルス事件」報告書

TSG科学省調査委員会*2

感染ウイルス名称:Jerusalem (Friday 13th)

 イスラエルで初めて発見されたメモリ常駐型ウイルス. COM・EXE ファイル ともに感染し, 感染すると COM ファイルは 1813 バイト, EXE ファイルは 1808〜1822 バイトファイルサイズが増加する. また EXE ファイルは重複感染 する. 13 日の金曜日に発病し, 実行しようとするファイルを削除する. 感染 したファイルには "sUMsDos" の文字が含まれており, 発見は容易である. な お, このウイルスを改造したウイルスも多い.

 以下は, ウイルス感染にともなう一連の事件の概要である.

[事件発生]
 平成 7 年 5 月 12 日 (金) 午前, TSG 所有の EPSON N製パー ソナルコンピュータ PC-486GR (写真 1, 以下 486GR と表記) が突然 起動できなくなるという現象が確認された. 前日までは何の問題もな く起動していたことは, 多くの証言より確認されており, 当初, 起動 に必要な何らかのファイルが破壊されていると考えられた. ライブラ リアンによる調査では, ATOK8 に問題があり, AUTOEXEC.USR から削 除するとうまく行くのではないかとことであった.

[ソフトウェアが動かない]
 とりあえず, 起動だけはするようになったのだが, 一部のソフ トがメモリ割り当てに失敗したという謎のエラーを出して動かなくなっ てしまっていた. この時点で, ウイルス感染ではないかとの疑念が高 まり, チェックをしようとはしたのだが, DOS6.2 付属の VB98 (ウイ ルスチェッカ) さえ, その謎のエラーを返して動かないという有様で あった.

[会計作業の危機]
 12 日は会計簿提出締め切り日であった. 会計の N は Windows 上で Excel を用いてその作業を行っていたのだが, あと会計簿に計 算結果を写すだけ, という段階になって, ウイルス事件に遭遇, 例の 謎のエラーによって Windows は動かなくなってしまった. N はやむ を得ず, 電卓を用いて, 再度計算を行うことになった. N が会計簿を 学友会に提出したのは午後 9 時の締め切り直前であった.

[「去年の 5 月 13 日は金曜日」事件]
 翌 13 日, TSG では新入生歓迎コンパが行われることになって いた. 多数の部員が 305 に集合時間前からきており, その人達によっ て調査が行われていた. ウイルスは Jerusalem であるとの疑いが強 まった.
 コンパ委員の S は, 去年の 5 月 13 日が金曜であることに気 付き, 486GR の内蔵カレンダを 1994 年 5 月 13 日にすれば, Jerusalem に感染していることが確認てきるのではないかと考え た. 結局, 彼の考えは正しかった. 486GR 時間 94 年 5 月 13 日 (金), ウイルスは嬉々としてその邪悪な活動を開始, これによって, 486GR につながっていた HDD 内の多数のファイルが失われた.
 その後, 他の部員によってウイルスチェッカを用いたウイルス チェックが行われ, 感染ファイルのマーキングが行われた.

[ウイルス生存を確認]
 15 日, また 486GR にて謎のエラーが確認された. 13 日にウ イルスが除去されきっていなかった可能性が大きかった. 結局, この ことにより, HDD の再フォーマットが行われることになった.
[386V に感染]
 翌 16 日, 今度はやはり TSG 所有の EPSON 製パーソナルコン ピュータ PC-386V (写真 2, 以下 386V と表記) にて, 例の謎のエラー メッセージが確認された. ウイルス感染が確認され, 一時 386V は使 用禁止となった. 486GR からコピーした「ブロックでポン!」が感染 源と考えられたが, 特定には到らなかった. 結局 HDD 再フォーマッ トにて, ウイルスは除去された.

▼被害にあった PC-386V
[再度 486GR に感染]
 5 月 22 日 (月), HDD 再フォーマット後, やっと環境が整い 始めていた 486GR にて再度ウイルスが確認された. 感染源は CPU ベ ンチマークプログラムであった. 週末に何者かがインストールしたも のと考えられた. 305 内に一時冷たい空気が流れたが, 幸運にも, 即 座に DOS6.2 付属の VB98 にて除去された. 同日, KGB のパソコンも ウイルスに感染していたことが発覚 (感染源は 486GR の「ブロック でポン!」らしいが) , このベンチマークプログラムは KGB のパソコ ンの HDD からコピーしたものではないかとの説もある.

 この後, ウイルス被害はない模様であるが, 部員の中に個人所有のパソコン の HDD が Cascade に侵された者がいるとの情報もある. 今後とも注意を怠ら ないことが必要である.

[「なぜか会計がこの記事を書いている」事件]
 ウイルスに関する記事を, 編集長は当初ライブラリアンの G に頼んだが, 「何も知らん」といって拒否され, 次に, かのコンパ委 員 S に頼んだそうだが, 「バイトが忙しい」といって断られたそう な (私から見るとSは暇そうだが). で, なぜか会計の N がこの記事 を書いている.

[「TEA さんがウイルスの記事を先に書いてしまった」事件]
 他の人がすでに書いた話題を書くのはむずい. *3

[「よく考えたら『コンパ委員 S 』に該当する人物が2人いる」事件]
どちらかは, ご想像にお任せします, ということで.

[「コンパ委員 S が怒り出しちゃうかも知れない」事件]
やっぱり 1 度本人に読んでもらわんとまずいだろうなあ*4. 頼む. >ちょもら

[「編集長のハンドル名は『ちょもらんま』だった」事件]
「ちょもら」の方がかっこいいとおもうけどなあ. (どんどん話 題がそれていく . . . )

焼き立てのクッキーよ:-)

[「この記事, 部報に間に合うのだろうか」事件]
タイトルそのまま.

[「最近は事件が多い」事件」
おいおい(^^;

文責 : Nishi


ひまわりの季節です

〜週刊ファミコン通信取材顛末記〜
ちょもらんま

 去る 5/16 (火) に, アスキー (株) の雑誌「週刊ファミコン通信」の編集 部の鈴木さんという方が, 取材のために TSG を訪れました. なんでも, 「ど の大学に行けば充実したゲームライフが送れるか ?」というテーマで, あちこ ちの大学のコンピューターサークルを取材しているのだそうです.
 ここでは, なぜか前回の工学者のときに続いて取材担当になってしまった私 が, 取材の顛末を報告したいと思います.

■印刷中に……
 5/12 日, 学館のロビーで190号の前半部を印刷していたときの こと. いきなり「TSG の方, お電話です」と放送がありました. 出て みると, なんと天下のアスキーからで, TSG を取材したいとのことで した. 「どの大学に行けば充実したゲームライフが送れるか ?」とい うテーマで, あちこちの大学のコンピューターサークルを取材してい るのだそうです. 工学社に次いで, 今度はアスキー……. う〜む, な かなかすごいかも(^^;) .
 取材には, 5/16 日 (火) の 4 限に来ていただくことにしまし た.

 また, 取材に先立ち, TEA さんから「記事のどこかに『いつだっ てひまわり』といれてもらえませんでしょうか」との要望がありまし た.

■取材当日は……
 平日 (火曜日) の午後ということで, あまり部員が集まらない のではないかと心配していたのですが, Makken さんや光田さんをは じめ 10 人以上の人が集まってくれました. 来て下さった皆さん, ど うもありがとうございました.

 校内で写真を撮るための許可は下りなかった*5ので, やむを得ず駒場の正門前に行き, メンバーの集 合写真と, SkyDuel の作者 Makken さんの写真を撮りました.
 その後, 部室でいろいろとお話をしました. 普段どんな活動を しているのか, どの辺のゲーセンに行くのかなどです. ファミ通の取 材だけあって, ゲーム関係の話題はかなりマニアックでした ね. (^^;)
 鈴木さんは, お話のあとで, 「皆さんが大人で本当に助かりま した. 」と言っていました. なんでも, 「昨日千葉大に行ったときは, 部員同士で喧嘩を始めちゃったりして (!) 大変だったので, 今日も 覚悟して来た」のだそうです. むぅ.
 最後に, 最近の部報と SkyDuel の最新版を持っていってもら いました. TEA さんの「いつだってひまわり」も, ちゃんと頼んでお きました(^^;).

■そして……
 TSG の紹介記事は, アスキー (株) の「週刊ファミコン通信」 7/7号 (6/24 発売) に掲載されました. 158 ページの上 1/3 くらい で簡単な紹介がされています. 部室に置いておくので見てください.
 TSG は登場しているのは, 158 ページだけではありません. 次 の 159 ページの「大学サークル事情」という囲みの最後のところに も, こんな文章が載っていす.

> ……大きなサークルには, “分科会”というかたちで, サークル内サークルがあ
> ることも. たとえば東大の TSG のなかには, スケボー分科会やサッカー分科会, 
> いつだってひまわり分科会などがあるのだ. 


ごみ4.LZH

TEA

 はっきり言って, プログラミングは前回から全くすすんでいません. (^^;  そこで今回は, 前回書いた LHA のバグらしきものがどうなったかを書こうと 思います.

 前回の部報がでたのが 5 月 13 日で, 次の日に, ったく☆さんが NIFTY の FLABO に LHA 2.66 の動作のことを書いてくださいました. かなり強い口調で (笑). すると, 5 月 17 日に LHA の作者の吉崎さんの書き込みがあって, 次 のバージョンで修正するということでした.
 そして, 5 月 28 日に LHA 2.67 がでました. どういうふうに変わったかを 簡単に書くと, 文字列の比較をしようとするアドレスが圧縮するテキストより 前にあるかを判定するようにしただけです. FLABO LIB 4 の AR950528.LZH で は次のようになっています.

    scan_end = (pos > DICSIZ) ? pos - DICSIZ : 0;
    if (scan_end < scan_limit) scan_end = scan_limit;
    scan_end += off;
scan_limit は最初は 100h で, 次にディスクを読むと 0 になります. off は ずらす量です. といぬ。に書いたことをそのままのせています. (^^; ぼくは この if 文をいれるのがいやだったので, if 文が常になりたつとしています. まあこれは off が 0 でないときしか関係ないので, 圧縮率はほとんど変わら ないだろうと信じています. (^^;

というわけで, 問題はあっさり解決してつまらないのですが(笑), NIFTY の昔 の log を見てみるとなかなか謎なことがあるので少し書こうと思います.

 >  高速化するときに, 読み込んだファイルの先頭よりもさかのぼって検
 >索してしまう可能性が生じたのを見逃していました. AR でも text バッ
 >ファを初期化していないので, 同じ状況になると思います. 
 これは LHA 2.60 のバグ修正に関する NIFTY の去年の書き込みです. ぼく はこれを読んだときは何のことかさっぱりわからなかったのですが, 実は例の バグらしき動作のことを言っています. LHA はファイルの前に256個のスペー スを置くことによって解決したわけですが, このときに自己解凍ルーチンでは 解凍できないことに気づいてほしかったですねえ.
 >  先日, ある方から sfx で展開できないという具体的なレポートを頂き, 
 >数日かかってようやく原因が判明しました. それでも今の今まで, 以前
 >のレポートとの関連には気付いていませんでした. 
 これは今年の 5 月 17 日のものです. どうやら吉崎さんは昔のことを忘れ ているらしい(笑). AR950528.LZH の encode.c の日付は 5 月 5 日になって いるので, その日には気づいていたみたいですが, だったらさっさと NIFTY に書いてほしかったです. :-)

 では, SFA のことですが, 最初に書いたように全くすすんでいません. (^^;
 夏休みになったらすこしはやろうと思うけど, 夏休みなんてあるのかな あ. (^^; そんなかんじで次のネタは全くないので原稿が書けるかどうかわか らないのですが, 64K 辞書の PKZIP が手に入ったらそれについて書こうと思 います. :-)

 あ, 7 月 13 日はもりぴーのコンサートに行きます. (^^)
 7 月 27 日にも行きます. なんと最前列です. どきどき.
 というわけで, 合宿には行きません. ごめんなさい.


なおの C 言語入門番外編

Xlib を使って情報棟でグラフィックプログラムを作ろう

なお

まえがき

 過去 4 回の TSG の部報にわたって「C/C++ 入門」を何回か連 載してきましたが, あれで文法的なことはもう十分言い尽くしたと思 います. 前回でもう C 関係の話はおしまいにするつもりだったんで すが, わけあってまた書くことなってしまいました.

 さて, ECC (Educational Computer Center (教育計算機センター)) を使い始めた皆さん, X Window には慣れたでしょうか ?
 駒場の情報教育関連施設には合計 1000 台もの X 端末があり ます. そして, そのどこからでも自分のあるいは他人のプログラムが 実行できます. これは非常に便利なことではないでしょうか.
 どこからでも開発ができ, みんなに見てもらえるのですから開 発者にとってはプログラムの作りがいのあり, 楽しいことです.

 ここには 1 から 10 までの和を求めるプログラム課題に悩ん でいる人から事務室のXぷよチェッカーに見つかって叱られている人 まで様々な人がいます.
 このような環境において, 自分の華麗なプログラムを披露して みようではないですか. 一般の人にプログラムの実行結果を見せて喜 んでもらうには, やはり綺麗なグラフィックを書くのが一番簡単でしょ う.

 というわけで, 今回は X Window でグラフィックプログラムを 作る方法をお話ししていきます.

 プログラミング言語はもちろん C/C++ を使いますが, その方 言は gcc (グヌーシープラプラ) です. そして, グラフィックライブ ラリには Xlib (エックスリブ) を使用します.
 この gcc コンパイラや Xlib はすべて駒場の WS の中にある ので, 買ったりコピーする必要はありません. すぐに始められます.
 この Xlib を使った X Window のプログラムは MS-Windows で のそれよりずっと簡単です. ほとんど DOS のときと同じです. なの で, ウィンドウについての深い知識は全然いりません.
 なお, この文章を執筆する際に僕が非常に参照した本を紹介し ておきます.
日刊工業新聞社
X-Window Ver.11 プログラミング [第 2 版]
木下凌一・林秀幸 著
 僕がここに書いた文章を読んで Xlib に興味を持った方は, ぜ ひこの本を買いましょう. 生協に一冊ぐらいは置いてあるでしょ う. 早めに買いに行くべきですね.

▼情報教育棟

第 1 章 ウィンドウを開きましょう

サーバー・クライアントモデル
 プロセスとプログラムの違いは知っていますか ? 簡単に言え ばプログラムはディスクに記憶されている動いていない命令群で, プ ロセスはモメリーに載せられて実行されている命令群のことです.
 X Window のシステムでは2つのプロセスが同時に動いて種々の 作業をすることが多いです. ひとつはクライアントと呼ばれて, 命令 (サービス・リクエスト) を発信するプロセスです. もうひとつはサー バーと呼ばれて, 命令を受けて実行するプロセスです. これをサーバー クライアントモデルとかと呼びます.
 このように指導者と実行者をわけるとなにかと便利ですよ ね. ここで注意ですが, このモデルはプログラムの構造化とは全然違 う仕組みです. 実際に 2 つのプロセスが同時に動いて別々の処理を するのです. 構造化プログラムは, 実行者が実行中は指導者はなにも しません. しかしサーバークライアントモデルでは, 実行者が実行中 でも指導者は次の命令を計画しています. まあ正確に言えば「同時] ではなく代わりばんこに動くのですけどね. でも CPU の有効活用に なります.
 しかし逆にこれが災いして不幸を招くこともあります. 指導者 が実行者の状況を考えずに次から次に命令を発すると実行者はパニッ クになって命令が実行されないという状況も起こります.
 というわけで, クライアントとサーバーとがうまく協調してい けるようにプログラムを作っていかなければなりません.

ディスプレイサーバーとの接続
 さて前置きが長くなりましたが, グラフィックの話を始めましょ う.
 まず最初にしておかなければならないことは, クライアントと ディスプレイサーバーの接続です. クライアントとはここでは自分が 作ったプログラムのプロセスのことです. ディスプレイサーバーは CRT を管理実行するサーバーです. これには XOpenDisplay() 関数を使います.
[prototype]
    Display* XOpenDisplay( char* display_name );
 display_name とは, その名の通りクライアントが接続 したいディスプレイのサーバーの名前です. 通常の使用では, 自分が 使っている CRT のサーバーと接続したいのでここは NULL にします. こうすると環境変数 DISPLAY の値が自動的に参 照されてうまくいきます.

 他人のディスプレイ上にウィンドウを開きたいなら, ここにそ のディスプレイサーバー名を書きます. 例えば eccーxs510:0.0 とす ると, 駒場の情報教育北棟の2階の大演習室の入り口入ってすぐの端 にある端末の画面にウィンドウがでます.
 しかし, こんなことが気やすくできたら, ウィンドウを出され るほうは迷惑ですよね. 簡単に嫌がらせができるのですから. という わけで, 実際は他人のディスプレイサーバーとは接続できないように なっています. でもその人にシェルから
  % xhost +
と唱えてもらえばできるようになります. しかしこれは何かと危 険ですのでやめましょう.

 この XOpenDisplay()Display 型のポ インターを返します. Display 型とは, ディスプレイに関 するいろいろな情報を格納する構造体です. 以後このディスプレイに 対する命令はこの Display 型構造体のアドレスを用いて識 別されます.
 ついでにディスプレイサーバーとの接続の解除の方法を述べて おきます.
[prototype]
    void XCloseDisplay( Diplay* display );
説明はいりませんね.

ウィンドウの設定と操作
 次にウィンドウを開きます.

 ウィンドウを開く際に必要な引き数としてなにが考えられます か ?
 まず, ウィンドウの位置と大きさの値が必要ですね. そしてウィ ンドウの色もあげたいです. そして肝心なのがそのウィンドウがどの ディスプレイのどの親ウィンドウの子ウィンドウなのかの指定です.
[prototype]
    Window XCleateSimpleWindow( Display* display, Window parent,
            int xo, int yo, unsigned int width, unsigned int height,
            unsigned int border_width, unsigned long border_color,
            unsigned long ground_color );

display        はディスプレイ ID です. 
parent         は親ウィンドウのウィンドウ ID です. 
(xo,yo)        は親ウィンドウ上の座標での子ウィンドウの左上隅の座標です
(width,height) はウィンドウの縦と横の大きさです. 
border_width   はウィンドウの枠の太さです. 
border_color   は枠の色のピクセル番号です. 
ground_color   は背景の色のピクセル番号です. 
返り値はできあがった子ウィンドウのウィンドウ ID です.
これでウィンドウがひとつできます. (この段階では表示はされ ません) Window 型とはウィンドウの ID を格納する型です. int 型の typedef と思われます.
 一番親のウィンドウのことをルートウィンドウと呼びます. こ のルートウィンドウの ID の入手方法はいろいろありますが, 一つだ け紹介します.
[prototype]
    RootWindow( Display* display );
これは関数ではなくマクロです. xlib.h で次の用に定 義されています.
 #define RootWindow(dpy, scr)    (ScreenOfDisplay(dpy,scr)->root)
なんだか良く解りませんが呪文のように使ってください.
 さて, このウィンドウを表示させるには XMapWindow() を使います.
[prototype]
    void XMapWindow( Display* display, Window window );
逆にこのウィンドウを非表示させるには XUnmapWindow() を使います.
[prototype]
    void XUnmapWindow( Display* display, Window window );
このウィンドウの全体をクリアさせるには XClearWindow() を使います.
[prototype]
    void XClearWindow( Display* display, Window window );
非表示ではなくウィンドウを完全に消滅させるには XDestroyWindow() を使います.
[prototype]
    void XDestroyWindow( Display* display, Window window );
説明はいりませんね.

ウィンドウマネージャの介入を防ぐ
 なんの指定もしないままウィンドウを開くと, そのウィンドウ はウィンドウマネージャによって管理されます. このウィンドウマネー ジャによって, 自動的にウィンドウにいろいろなアクセサリがついた り, プログラム実行中にウィンドウの位置や大きさをマウスで変えた りすることができて便利なのです.
 しかし, 不都合なことも起こります. ウィンドウの表示したて のころの描画命令がうまく実行されないということが起こるのです.
 理由はよく解りませんがこのウィンドウマネージャが原因であ ることは確かです. なのでウィンドウマネージャの介入を防がなけれ ばなりません. その方法については後のプログラム例で紹介します.

リクエストバッファ
 ひとつ大事なことを言うのを忘れていました. 命令はクライア ントで唱えられてすぐサーバーに送信されるのではなく, 一旦命令バッ ファ (リクエストバッファ) に貯められて幾つかリクエストがたまっ たらまとめてサーバーに送られます.
 したがって 2, 3 の命令が唱えられたぐらいではサーバーは動 きません. そこでこのバッファに少しだけたまっているリクエストを 強制的にサーバーに送らせる命令が必要になりますね. それが XFlush() です.
[prototype]
    void XFlush( Display* display );
命令群に一段落ついたらこれを唱えるようにしましょう.

プログラム例
 さて, ここらでやっとウィンドウ操作の基本的なプログラムが 作れるようになりました. ウィンドウを生成して消去するプログラム を作ってみます.
#include<X11/Xlib.h>                    // Xlib に必要なインクルード
#include<X11/Xutil.h>
#include<stdio.h>

Display* d;                             // ディスプレイポインタ
Window w;                               // ウィンドウ ID
XSetWindowAttributes att;               // ウィンドウ属性の変数

void main( void )
{
    d = OpenDisplay( NULL );            // ディスプレイサーバーとの接続
    w = XCreateSimpleWindow( d,RootWindow(d),100,100,800,600,5,0,1 );
                                        // ウィンドウの生成
    att.override_redirect = True ;
    XChangeWindowAttributes( d, w, CWOverrideRedirect, &att );
                                        // ウィンドウマネージャの介入を停止する
    XMapWindow( d, w );                 // ウィンドウの表示
    XFlush( d );                        // リクエストの強制送信
    getchar();
    XDestroyWindow( d, w );             // ウィンドウの消去
    XCloseDisplay( d );                 // サーバーとの接続の解除
}
 これで枠が白の黒いウィンドウができました. めでたし.

コンパイルの仕方
 ヘッダーファイル Xlib.hXutil.h に 必要な関数やマクロの定義があるのでこれらをインクルードしておき ます.
 そして, このソースファイルの拡張子は必ず .cc に してください. 他の拡張子ではコンパイラは Bad magic number を返 して受け付けません.

そして肝心のコンパイルの方法は, このファイルの名前が cg_test.cc なら
% gcc -o cg_test cg_test.cc -I/usr/local/X11R6/include -lX11 
    -L/usr/local/X11R6/lib
です. -o の後ろの文字列が実行ファイル名で次の文字 列がソースファイル名そして次の長い文字列はインクルードファイル と X ライブラリのありかを示すオプションです. 数学関数を使用す る場合はさらに -lm のオプションを付けてください.
 こんなに長い命令を毎回唱えるのはかなり煩わしいですね. csh (要するにバッチファイルのようなもの) にしてしまいましょう.
  #!/bin/csh -f
  gcc -o $argv[1] $argv[1].cc -I/usr/local/X11R6/include -lX11 
  -L/usr/local/X11R6/lib -lm
この長い gcc のコマンドは一行にして書いてください. これを 例えば compile という名のファイルにして
  % chmod u+x compile
とすれば,
  % compile cg_test
でコンパイルできるのでとても便利です.

第 2 章 お絵描きをはじめましょう

GC グラフィックコンテキスト
 いよいよお絵描きの始まりです. (人はこのような書き方をオ タッキーと呼ぶ)

 でも絵を書く前に, 何色で書くのか, どんな模様で書くのかと かを設定しておかなければなりませんね.

 DOS 系の C 言語のグラフィックライブラリには (多分どの方 言でも同じだろうと思いますが) setcolor() とか setlinestyle() とかがありましたね. これらは設定を変え たいとき事に呼び出さなければなりませんでした. これらの状態を管 理する変数がひとつだけあって, そこに代入することによって設定を 変えているのですから仕方ありませんでしたね.
 しかし Xlib では少し様子が違います. このような描画の仕方 を管理する変数達がひとつの構造体にまとまって GC (グラフィック コンテキスト) と呼ばれる XGCValues 構造体になっていま す. そしてこの構造体を幾つも宣言することができるので, 描画の際 にどの XGCValues 構造体を参照するかを指定することによっ ていろいろな色・模様の図形をいちいち設定変更無しに描けるのです. この XGCValues構造体の ID を格納するのが GC 型の変数です.

 ひとつ GC を作ってみましょう. XCreateGC() を使 います.
[prototype]
    GC XCreateGC( Display* display, Drawable drw,
             unsigned long mask, XGCValues* values );
この Drawable という型は Window 型と同じ と思って構いません. 実際ここにウィンドウ ID を指定します. この maskvalue は使わないでも何とかなるので説 明しません. こんなふうに使います.
    GC gc;
    gc = XCreateGC( display, window, 0, 0 );
 こうするとデフォルトに設定された GC が出来上がります.

 GC の内容を変更するにはいろいろな方法があります. GC が管 理している変数はたくさんあるのでその一部だけを変更する関数を極 一部だけ紹介します.
[prototypes]
    XSetFunction( Display* display, GC gc, int function );
    XSetForeground( Display* display, GC gc, unsigned long color );
    XSetBackground( Display* display, GC gc, unsigned long color );
 XSetFunction() は描画の際に or で書くか and で 書くか等の論理の設定をします. 僕がよく使うのは function=GXxor として xor で書くときです.
 XSetForeground() は図形の色を設定します. 
 XSetBackground() は 2 色の色を使う図形のもう一方の色を設定します. 
他にもたくさんの GC 変更関数がありますが詳しくは他書にゆず ります.

色について
 XSetForeground() に与える色番号はピクセル番号 (パレット番号) です. 0 から 255 までありますが, どの番号にどん な色が対応しているのかはマシンによって異なります. このことにつ いては後でもう少し詳しく話します.

描画関数の紹介
 これは簡単なので簡略して紹介します. 使用例も割愛します.
[prototypes]

◎-------点を描く関数----------

 一つの点
    void XDrawPoint( Display* display, Drawable drw, GC gc,
                     int x, int y );

   (x,y)に点を描きます. 

 複数の点
    void XDrawPoints( Display* display, Drawable drw, GC gc,
                      XPoint* points, int num, int mode );

   XPoint型の構造体は下記のように定義されています. 
    typedef struct {
        short x, y;
    } XPoint;

   numの値は描く点の数
   modeの値が CoordModeOrigin なら絶対座標で点を打ち
   modeの値が CoordModePrevious なら前の点からの相対座標で点を
   打ちます. 

◎------直線を描く関数----------

 一本の線分

    void XDrawLine( Display* display, Drawable drw, GC gc,
                 int xs, int ys, int xe, int ye );

   (xs,ys)-(xe,ye)に直線を引きます. 

 連続直線

    void XDrawLines( Display* display, Drawable drw, GC gc,
                 XPoint* points, int num, int mode );

     points,num,modeはXDrawPoints()と同じです.  

 複数の線分

    void XDrawSegments( Display* display, Drawable drw, GC gc,
                 XSegment* segments, int num );

   XSegment型の構造体は下記のように定義されています. 

    typedef struct {
        short x1, y1, x2, y2;
    } XSegment;

◎------長方形を描く関数--------

 一つの長方形の境界線

    void XDrawRectangle( Display* display, Drawable drw, GC gc,
                     int xo, int yo, unsigned int width, 
                     unsigned int height );

   (xo,yo)を左上隅の座標とし横 width 縦 height の長方形を描きます. 

 複数の長方形の境界線

    void XDrawRectangles( Display* display, Drawable drw, GC gc,
                     XRectangle* rectangles, int num );

   XRectangle型の構造体は下記のように定義されています. 

    typedef struct {
        short x, y;
        unsigned short width, height;
    } XRectangle;

 一つの長方形を塗り潰す

    void XFillRectangle( Display* display, Drawable drw, GC gc,
                     int xo, int yo, unsigned int width,
              unsigned int height );

 複数の長方形を塗り潰す

    void XFillRectangles( Display* display, Drawable drw, GC gc,
                     XRectangle* rectangles, int num );

◎------円弧を描く関数-----------

 一つの円弧

    void XDrawArc( Display* display, Drawable drw, GC gc,
                  int xo, int yo, unsigned int width,
          unsigned int height, int start_angle,
          int draw_angle );

   (xo,yo)を左上隅の座標とし横 width 縦 height の長方形にぴったり収まる楕円弧で, 開始角度がx軸より左周りstart_angle/64度で左回りにdraw_angle/64度だけの楕円弧を描きます. 

 複数の円弧

    void XDrawArcs( Display* display, Drawable drw, GC gc,
                  XArc* arcs, int num );

   XArc型の構造体は下記のように定義されています. 

    typedef struct {
        short x, y;
        unsigned short width, height;
        short angle1, angle2;
    } XArc;

 円弧を塗り潰す

    void XFillArc( Display* display, Drawable drw, GC gc,
                 int xo, int yo, unsigned int width,
                 unsigned int height, int start_angle,
                 int draw_angle );

 複数の円弧を塗り潰す

    void XFillArcs( Display* display, Drawable drw, GC gc,
                  XArc* arcs, int num );

◎------多角形を塗り潰す関数--------

    void XFillPolygon( Display* display, Drawable drw, GC gc,
                    XPoint* points, int num, int shape, int mode );

   shapeの値は凸多角形の時はConvexにしてください. 
   そうでない時やわからない時はComplexにしてください. 

お絵描きの例
 やっぱり例をしめさないといけませんね.
 よくありがちですが, ダイアモンドパターンを描いてみましょ う.
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<stdio.h>
#include<math.h>

#define N 16
#define PI 3.141592653

Display* d;
Window w;
GC gc;

void main( void )
{
    int x[N],y[N];
    int i,j;

    d = OpenDisplay( NULL );
    w = XCreateSimpleWindow( d,RootWindow(d),100,100,800,800,5,0,1);
    XMapWindow( d, w );

    gc = XCreateGC( d, w, 0, 0 );
    XSetForeground( d, w, gc, 6 );

    for( i=0 ; i<N ; i++ ){
        x[N] = (int)350*cos(2*PI*n/N)+400;
        y[N] = (int)350*sin(2*PI*n/N)+400;
    }

    for( i=0 ; i<N ; i++ ){
        for( j=i+1 ; j<N ; j++ ){
            XDrawLine( d, w, gc, x[i], y[i], x[j], y[j] );
        }
    }

    XFlush( d );
    getchar();
    XDestroyWindow( d );
    XCloseDisplay( d );
}
これで 6 番色でダイアモンドパターンが描けると思います. 実 行してチェックしていないのでバグがあるかもしれません.

第 3 章パターンイメージの操作

 ちょっとした小さな絵を getimage() 関数などを使っ て vram 以外のメモリーに蓄えて, それを vram のあちこちに putimage() することがよくありますね. ここではそれを X Window 上でする方法について紹介します.

ピックスマップに図を書く
 getimage するには, まずその絵を vram に書かなく てはなりませんでした. しかしプログラムの実行の最初に, すみっこ でちょこちょこ書くのも, あまり格好良くありません. 裏仕掛けがば れてしまうようですし, あまり見られたくないものですよね.
 X Window にはそうした要望から「見えないウィンドウ」とい うものがあります. それがピックスマップです. しかもピックスマッ プにはウィンドウのようなややこしい主従関係や枠や背景色がありま せん. 純粋にイメージデータの作業場としてのウィンドウなのです.
 ウィンドウ ID の Window 型とピックスマップ ID の Pixmap 型を総して Drawable 型としていたのです. これで Drawable 型が何 者かが解ってくれたでしょう.

 ピックスマップを生成するには XCreatePixmap() 関 数を使います.
[prototype]
    Pixmap XCreatePixmap( Display* display, Drawable drw
            int width, int height, int depth );
見えないのですから位置を指定する必要はないですね. この drw はなんで必要なのでしょうかねえ. 解りません. とりあえず手短なウィ ンドウ ID をいれておけば良いようです.
 ピックスマップを開放するには XFreePixmap() 関数 を使います.
[prototype]
    void XFreePixmap( Display* display, Pixmap pixmap );
 ピックスマップに絵を書くのは簡単です. だって Drawable 型と Pixmap 型は意味がほとんど同じ だからです. いつものようにするだけです.
 ピックスマップに円を書くプログラムの断片を載せます.
    Pixmap pix;
    pix = XCreatePixmap( display, window, 10, 10, 8 );
    XDrawArc( display, pix, gc, 0, 0, 10, 10, 0, 360*64 );
簡単でしょ.

ピックスマップの図をウィンドウにコピーする
 次はこのピックスマップの絵をウィンドウにコピーします.
 一般に 2 つの drawable 間の図形のコピーには XCopyArea() 関数を使います.
[prototype]
    void XCopyArea( Display* display, Drawable source,
            Drawable destination, GC gc,
            int source_xo, int source_yo,
                unsigned int source_width,
             unsigned int source_height,
                int destination_xo, int destination_yo );

   source : コピー元の ID です. 
   destination : コピー先の ID です. 
   gc : コピーの際の描画方法を設定しておきます
   (source_xo,source_yo) , source_width , source_height :
        コピーする長方形領域を指定します. 
   (destination_xo,destination_yo) : コピー先の左上隅の座標です. 
パラメータが多いのが面倒ですが, これで putimage 関数になります.
使用例の断片
    Pixmap pix;
    pix = XCreatePixmap( display, window, 10, 10, 8 );
    XDrawArc( display, pix, gc, 0, 0, 10, 10, 0, 360*64 );
    XCopyArea( display, pix, window, gc, 0, 0, 10, 10, 100, 100 );
これでウィンドウの (100, 100) に円が写されます.

第 4 章 カラーマップと色操作

 X Window のグラフィックのフレームメモリには 8 枚のプレー ンがあります. ひとつのプレーンの 1 ビットがウィンドウのひとつ の点に対応しているので, 同時発色可能な色の数は 2 の 8 乗で 256 色になります.
 その 256 個のパレット (カラーセル) に対してひとつずつ RGB の強度が 65536 段階でセットできます. つまり色の種類はなん と約 280 兆色にもなるのです. でも人間の目には識別できないでしょ う.
 デフォルトで設定されている色は 24 色ぐらいであまり綺麗な 色ではありません. それに, パレットに何色が入っているかはマシン によって異なります. ですから自分で色を作らなくてはなりません.
 ここではその方法のうちのひとつであるプライベートカラーセ ルについて説明します.

物理カラーマップの ID の入手
 256 個のカラーセルを格納する変数をカラーマップと呼びます. カラーマップは自分でいくらでもつくれますが, 実際ハードウェアが 参照するカラーマップのことを物理カラーマップと呼ぶます. 他のカ ラーマップは仮想カラーマップと呼ばれます.
 サーバーの起動時に物理カラーマップになるものをデフォルト カラーマップと呼びます. このデフォルトカラーマップの先頭の 24 色ぐらいは共有カラーセル領域と呼ばれ, 複数のウィンドウに共有さ れています. よって, この部分は書き換えることはできません. 残り のセルは, 各々のウィンドウで独自に使用できるセル領域です. よっ て自由に書き換えれます. これをプライベートカラーセル領域と呼び ます.

 さて, このデフォルトカラーマップの ID を手にいれる必要が あります. それには, マクロ DefaultColormap() を使いま す. カラーマップ ID が Colormap 型の変数として返って きます.
[prototype]
    Colormap DefaultColormap( Display* display, int screen_num );
通常 screen_num は 0 にしてください.

プライベートカラーセルの確保
 さてと, これで例えば 128 番パレット (つまりピクセル値 128) にオレンジ色を作れるかというと, そうはいかないのです.
 先に作ったカラーマップ上にカラーセルを記憶する領域を確保 しなければならないのです. これには XAllocColorCells() 関数を使うのですが, この関数は少々ややこしいので, じっくり取り 組んでください.

 まず了解してもらいたいことは, 特定のピクセルにアロケート (確保) することはできないということです. つまり, この関数が勝 手にピクセル番号を決めてくれるのです.
 そしてそのピクセル番号は普通に 0〜255 の値で返ってきませ ん. 複数のピクセルをアロケートした場合, それらのピクセル値のそ れぞれはベースピクセル値と幾つかのプレーンマスク値の組み合わせ との論理和で表されるように幾つかのベースピクセル値とプレーンマ スク値が返ってくるのです.
 引き数としては, アロケートするピクセルすべてが表せられる だけのベースピクセルとプレーンマスクの枚数を指定するのです.
 なんだか, わからなくなってきたでしょう.

 ベースピクセル値を格納する配列を b_pixel[2], プ レーンマスク値を格納する配列を p_mask[3] としましょう. これらには例えば次のような値が入ります.
    p_mask[0] : 00000001       b_pixel[0] : 00010000
    p_mask[1] : 00000010       b_pixel[1] : 00011000
    p_mask[2] : 00000100
 本当はこれらの値は long 型なので桁はもっと多い のですが全部 0 なので無視しました. p_mask[] の値は下 3 桁のお互い異なるひとつのビットだけが立っていま す. b_pixel[] の値は下3桁が0でその上の桁に適当な 2 種 類の値が入っています.
 この 3 つの p_mask[] のうちの幾つかの値の or し たものに b_pixel[] のどれかひとつの値を or してピクセ ル値が表されるのです.
 つまりこの場合は次のようにして16種類のピクセル値が表され ます.
                                      b_pixel[0]     =  00010000
                                      b_pixel[1]     =  00011000
  p_mask[0]                         | b_pixel[0]     =  00010001
  p_mask[0]                         | b_pixel[1]     =  00011001
  p_mask[1]                         | b_pixel[0]     =  00010010
  p_mask[1]                         | b_pixel[1]     =  00011010
  p_mask[2]                         | b_pixel[0]     =  00010100
  p_mask[2]                         | b_pixel[1]     =  00011100
  p_mask[0] | p_mask[1]             | b_pixel[0]     =  00010011
  p_mask[0] | p_mask[1]             | b_pixel[1]     =  00011011
  p_mask[0] | p_mask[2]             | b_pixel[0]     =  00010101
  p_mask[0] | p_mask[2]             | b_pixel[1]     =  00011101
  p_mask[1] | p_mask[2]             | b_pixel[0]     =  00010110
  p_mask[1] | p_mask[2]             | b_pixel[1]     =  00011110
  p_mask[0] | p_mask[1] | p_mask[2] | b_pixel[0]     =  00010111
  p_mask[0] | p_mask[1] | p_mask[2] | b_pixel[1]     =  00011111
 面倒な仕組みですけれど, わかってくれたかな. この 16 種類 のピクセル値がすなわちアロケートされたパレット (カラーセル) の 数であることは, 言うまでもありませんね.
 プレーンマスクの枚数を plane_num, ベースピクセ ルの枚数を pixel_num とするとアロケートされるカラーセ ルの数 cell_num は次の式で表されるのは明らかですね.
           cell_num = pixel_num * pow( 2, plane_num );
 あとアロケートに必要な引き数として, アロケートされるプレー ンマスク値が連続していて欲しいかどうでもよいかを指定する引き数 があります.
 以上でようやく, XAllocColorCells() 関数の [prototype] が示せれます.
[prototype]
    Status XAllocColorCells( Display* display, Colormap cmap,
       Bool continue,
         unsigned long  p_mask[], unsigned int plane_num, 
         unsigned long b_pixel[], unsigned int pixel_num );
 Status 型と Bool 型は共に単なる int 型です. continueTrue とすれ ば連続したプレーンマスク値が得られます. 返値はアロケートがうま く失敗すると False を返します.

カラーセルに RGB 値を設定する
 さあいよいよ, RGB 値の設定です. ひとつのカラーセルに一種 類の RGB 値を設定します. RGB の各値は 0L から 65535L までの値 が設定できます. 数値が高いほうがその原色の輝度が高いわけです.
 この設定には XStoreColor() 関数を使います. ピク セル番号と RGB の輝度を渡すのですが, これは別々に渡すのではな く一括して XColor 型の構造体にして渡すことになってい ます.
 XColor 型は Xlib.h の中で次のように定 義されています.
   typedef struct {
           unsigned long pixel;
           unsigned short red, green, blue;
           char flags;  /* do_red, do_green, do_blue */
           char pad;
   } XColor;
 この flags は輝度を書き換えるときに RGB のいず れだけを書き換えるかのマスクとして働きます. 通例 RGB すべて書 き換えるので, この値は
        flags = DoRed | DoGreen | DoBlue
としておきます. pad いまは使われていません.
[prototype]
    void XStoreColor(Display* display, Colormap cmap, XColor color);
これを唱えると, たちまちにその pixel の色が変わっ てしまうのです. 以上で自分の好みの色を作る方法がわかりましたね.

プログラム例
 赤色から黄色に128段階に階調された帯を並べるプログラムを 作ります.
#include<X11/Xlib.h>
#include<X11/Xutil.h>
#include<stdio.h>

Display* d;
Window w;
GC gc;
Colormap cmap;

void main( void )
{
    int i;
    XColor color;
    unsigened long p_mask[1], b_pixel[128];

    d = OpenDisplay( NULL );
    w = XCreateSimpleWindow( d,RootWindow(d),100,100,800,200,5,0,1);
    XMapWindow( d, w );
    gc = XCreateGC( d, w, 0, 0 );
    cmap = DefaultColormap( d, 0 );

    XAllocColorCells( d, cmap, True, p_mask[], 0, b_pixel[], 128 );
    for( i=0 ; i<128 ; i++ ){
        color.pixel = b_pixel[i] | p_mask[0] ;
        color.flags = DoRed | DoGreen | DoBlue ;
        color.red   = 65535L ;
        color.green = i*512L ;
        color.blue  =     0L ;
        XStoreColor( d, cmap, color );
    }

    for( i=0 ; i<128 ; i++ ){
        XSetForeground( d, w, gc, b_pixel[i] | p_mask[0]  );
        XFillRectangle( d, w, gc, i*5, 50, 5, 100 );
    }
    XFlush( d );
    getchar();
    XDestroyWindow( d );
    XCloseDisplay( d );
}
結構面倒ですね.

 デフォルトカラーマップを利用しているから, こんなに面倒な んですが, 新しくカラーマップを自分で作ってそれを物理カラーマッ プにインストールする方法ならもっと簡単になるでしょう. でもこの 方法はまだ僕が確認していないので説明しませんでした. それに何か 副作用がありそうだったのです.

第 5 章 グラフィックの結果をホー ムページに貼る

ウィンドウの絵をイメージデータファイルにする
 ウィンドウに表示されている絵を GIF 形式などの画像データ にする方法を説明します. GIF になればその絵をホームページに簡単 にはりつけることができます.
 まず, そのグラフィックプログラムを起動したのとは別のシェ ルを作ってください. または Ctrl-z してプロセスを裏に走らせてく ださい. そしてそのシェルで次の呪文を唱えてください.
  % xwd >imagedatafilename
 この imagedatafilename はテンポラルな名前で構い ません. そしてマウスを画像を取り込みたいウィンドウに持っていっ て, その中で左クリックします. 1 秒か 2 秒で取り込みが終わりま す.

イメージデータファイルを GIF 形式に変換する
 次に先のシェルから次の呪文を唱えてください.
  % xpaint imagedatafile
 すると電卓みたいなウィンドウが現れますが, もう少し待つと 取り込んだ絵を含むウィンドウが現れます.
 そこで file ダイアログの save as ウィンドウを開いて, ファ イル名をちゃんとした名前にします. GIF 形式にしたいなら拡張子は .gif にしてください. そして忘れてはいけないのが, そのウィンド ウ内にある GIF ボタンを押しておくことです. こうして OK ボタン をおすと, この絵は GIF 形式に変換されてセーブされます.

GIF データをホームページに貼る
 貼り方はとっても簡単です. 貼りたい所で
     <imag src=tsg191-"filename">
と唱えるだけです. データファイルのパーミッションを読み込み 可能にするのを忘れずに. 何らかのアクシデントがあって, そのデー タが読めないときにはホームページに がでます.

第 6 章 おまけ・ファイルの DOS/UNIX 間のコピーについて

復帰コードの対処法
 自宅の DOS マシン上で開発したプログラムを大学の ECC の WS にコピーしても, 実行はおろかコンパイルすらできないことがよ くありました. なおはこれに随分悩まされました. ちょっとしたミス でプログラム完成が 2 カ月も遅れてしまったりしました. 情報処理 中級の課題はコンパイルできないプログラムを提出して, 「DOS マシ ンでコンパイルしてください」とニュースに投稿していました.
 この原因は何だったのでしょうか. これは DOS と UNIX のテ キストの扱いの違いが大きいです.
 DOS のテキスト形式には改行のところに復帰コード 0x0d と改 行コード 0x0a が入っています. しかし UNIX では復帰コードが必要 ありません. むしろ, あると UNIX にとっては謎の文字として認識さ れ種々のトラブルを招きます. 特にコンパイラはこれに敏感に反応し, 各行で「謎のコードが入っている」とエラーを吐き挙げ句に「エラー が多すぎる」と見捨ててくれます.
 しかも厄介なことに, このコードは普通見えません. cat で見 てもなんともないように見えます. mule はこのコードに対応してい て, コードがあるファイルに対しては, 改行するとそのコードを自動 的にいれてくれます. これが余計なお世話だったんですね.
 このためこの復帰コード 0x0d を取り除かなければなりません. 去年の方法を載せると,
  % tr -d '\015' <oldfile >newfile
として 8 進数の 15 すなわち 13, すなわち 16 進数の d, つま り復帰コードを削除していました.
 しかし, 今年からは, こんな煩わしいことは必要ありませ ん. 南棟なら
  % mread -t b:fname .
のようにして ーt オプションを付けるだけでこの問題は解決され ます.
 北棟なら中演習室の FMV から FTP を使って簡単に何も気にせ ずにコピーできます.

漢字コードの対処法
 次の問題は漢字コードの変換です. DOS では大抵 SJIS コード を使っていますが, 大学の機械は EUC コードです.
 別に SJIS コードでも, cat や mule で化けませんが printf などで出力すると激しく化けます. やはり漢字コードの変換が必要で す. 次のようにします.
  % nkf -e oldfile >newfile
とします. この nkf コマンドは実は Network Kanji Filter の 略だったんですねえ, 知りuせんでした. さて, くれぐれも oldfile と newfile の名前を同じにしないでください. リダイレクションで は出力先のファイルを空にしてオープンしてからプロセスを実行する のです.
 この漢字コードの変換は自動的にはしてくれません. 毎回こま めに変換しましょう.
 逆に EUC から SJIS に変換するには
  % nkf -s oldfile >newfile
とします. 他にも
  % cat oldfile | euctosj > newfile
の方法がありますが, ファイルの変換にはあまり使いませ ん. EUC 非対応のマシンからアプリケーションを実行するときに使い ます.

いちおうコピーの仕方の説明 南北両棟
 フロッピーから WS へのコピーの仕方は知っていますか ? 北 棟の方の説明が「利用の手引きに」載っていないようですね. ついで に南棟のほうも説明しましょう.
北棟
 中演習室の FMV の電源スイッチをいれてくださ い. 待つこと数分. 途中で英語でキーを押すことの要求が出 ますが無視してください. やがて日本語でキーを押すように 指示がでるので, このとき初めてキーを押してください. ID とパスワードを入れてまたしばらく待つと, 桜の壁紙の MS-Windows が立ち上がります.
 プログラムマネージャの右下の WTISP アイコンを開 いてさらに FTP アイコンを開いてください. そしてセッショ ンボタンを押しオープンを選びます. ホストや ID を入力す るウィンドウが開くはずです. 入力してください. ホスト名 は xss50 とか ecc-xs70 とかが暇そうなのでいいでしょう. ID の入力の後, 警告メッセージが出でびっくりしますがな んでもないので
 パスワードを入れます. (周りの人を追い払えという 意味の警告だったんですね)
 次にフロッピーを FD にいれます. そこは A ドライ ブです. FTP ウィンドウの左側が FMV 側で右側がリモート ホスト側, つまり WS 側です. FD から WS にコピーしたい ときは FD 側のファイルをクリックして反転表示させて, WS 側のパスを選ぶのです. 逆は明らかですね.
 そして転送ボタンを押してください. 全部転送ボタン も押しましょう.
 これでコピーができました. めでたし. でも北棟の方 は起動するのに時間が掛かり過ぎます. そこがすこし面倒で す.

▼情報教育北棟
南棟
 各部屋に2台だけある IO サーバーを使います. 3.5 インチの 1.2M のフロッピーについてだけ説明します. まず この IO サーバーからログインしてください. フロッピーを (外づけの) FD に入れます. 側にあるスライドスイッチを A 側にしてください.
  > mdir b:
 としてフロッピーの内容が読めます.
  > mcd b:dirname
 としてフロッピーのカレントディテクトリが変更でき ます. ただし, 調子の悪いときもあります. それでも大抵う まく動きます.
  > mread -t b:fname .
 としてフロッピーのカレントディレクトリから WS の カレントディレクトリにコピーできます. ワイルドカードを 使うときや WS のサブディレクトリにコピーする際は次のよ うにします.
  > mread -t b:"*.*" ~/dirname
 逆もわかりますね.

あとがき

 以上で Xlib の解説はおしまいにします.

 Xlib の本当に最初のことだけの説明でしたが, これでそこそ このグラフィックプログラムが作れるようになれるでしょう. もっと 知りたくなったら, 前に挙げた本を読むことを強く勧めます.

 C 言語関連は前回でおしまいのつもりだったんだけど, かわり に依頼されていた「発狂君せんべい」の原稿がうまくすすまなかった ので急遽この Xlib の話にしてしまいました.
 編集長のちょもらんま君の期待に答えれなかった上に, このよ うな長文の原稿を提出してしまい, また彼を編集・印刷・製本の過労 に追込むことになってしまいました. (だから僕に気やすく原稿依頼 しちゃダメって言ったのに)

 しかし本当に長い文章になってしまいました. (1000行近くあ ります) オリエンテーション号での原稿に次ぐ長さです. これで誰も 読んでくれなかったらちょもらんま君がうかばれないですね. だから, 読みましょうね. (ここで言うのは遅いですね. まだ読んでいない人 に読むよう言いましょう(^_^;))

 最近, 部長のなおは情報棟にしょっちゅういます. 僕をみかけ た人も多いでしょう. これも, Xlib の使い方を知ってグラフィック プログラムがかけるようになったからです.
 僕のディレクトリに幾つかプログラムができています. ホーム ページにその紹介が載っているのでちょっと見てください. カオスや フラクタルなどの非線形力学系のシミュレートプログラムばっかりで すけどね.

 2 年生のみんなの進学先はどこになったのかなあ. 情報や電電 が多いのかな.

 なおはなんと基礎科第一になるでしょう. 来年も駒場です. あ と 4 年間も駒場に居るということです. 一年生の皆さんよろしくお 願いします.

では, みなさん ECC の楽しい世界を満喫してください.

なお, 渡辺 尚貴, g440056@komaba.ecc.u-tokyo.ac.jp


シケプリを作る人のためのゲスプリの使い方

ちょもらんま

■はじめに
 まもなくつらい試験期間がやって来ます. シケ対になっている 人も結構いるのではないでしょうか. 「あ〜あ, こんな科目のシケ対 やるんじゃなかった〜」とかなんとか言いながらもなんとかシケプリ を作ったら, 次には印刷が待っています.
 一番身近で手軽な印刷手段は何といってもコピー機ですが, コ ピー機では一枚ごとに 10 円もかかってしまいます. マイナーな科目 ならばいざ知らず, 語学などクラス全員に配る必要のある科目では, 印刷費用はとんでもない額になってしまいます. しかし, ゲスプリを 使えば, 印刷費がかなり安くすむばかりでなく, 領収書をもらってク ラス費から落としてもらうこともできますので, とってもお得です.
 そんなわけで, ゲスプリを使って印刷をするために知っておい てもらいたいことを, いくつか書いてみたいと思います.

 なお, 編集長の私には, 「みんながこの原稿を読んで印刷を手 伝ってくれれば, 仕事が楽になるなあ」とかいったような下心は, 一 切ありません(^^;).

▼ゲスプリのある学会ロビー

▼ゲスプリンター (左が新型, 右が旧型)

■キーカウンターを借りる
 ゲスプリは, 学生会館のロビーに A〜D の 4 台があります (繁忙期には, 204 号のプリントステーションにある旧型機 E〜G も 使うそうです) . これらのゲスプリは勝手に使えるわけではなく, 学 館の事務室で手続きして, キーカウンターというものを借りないと動 かないようになっています.

 まず, 順番待ち制のゲスプリンターについて説明しましょ う. ロビーの 4 台のうち B〜D の 3 台と, プリントステーションに ある E〜G の 3 台の計 6 台が順番待ち制になっています (E〜G は, 繁忙期のみ). これら 6 台のうち, 空いているゲスプリがあればキー カウンターはすぐに借りることができます.
 しかし, 試験前のような繁忙期には, 必ず誰かが使っているの でそうはいきません. キーカウンターが借りられないときは, 代わり に整理券をもらって自分の番がまわってくるのを待ちます. 「整理券 番号○×番の方, 印刷機が使用できます」という放送がかかるので, 自分の番号が呼ばれたら事務室に行って, 整理券と引換えにキーカウ ンターを借ります.
 なお, 3 回呼ばれてもキーカウンターを取りに行かなかった場 合には, 整理券は無効になってしまうので注意しましょう.

 一方, A のゲスプリンターは, 他の 6 台と違って予約制になっ ています. 事務室の窓口の前のゲスプリの予約状況を書いたファイル を見て, 空いている時間を探して予約をとってください. 予約は, 一 週間前から取ることができます.

▼プリントステーションには、ゲスプリ以外にもアヤシゲな印刷機が……
■紙
 コピー機では予め紙が用意されていますが, ゲスプリでは, 紙 は自前で用意しないといけません. 僕はシケプリを作るときはクラス ロッカーの中にあるシケプリ用の紙を使っていますが, そのようなも のが無い場合は, 事務室や生協で買いましょう.

 思いっきり汚い紙でもいいというのであれば, TSG の古い紙が あります. 部報には使えないけど, 何かの役に立つかもしれないので, そのまま置いてある紙です. この紙を使いたいときは, 僕に相談して ください.
 なお, この紙はときどき靴の跡がついていたりするので, 使う ときには覚悟して下さい. (^^;)

■印刷
  1. 用紙をセットする

     紙の束は, そのままセットしてはいけません. 印刷時に紙同士がくっ ついたまま何枚もいっぺんに取り込まれて, 白紙が出てしまうからで す. 岡村君に聞いたのですが, 雨の日など湿度の高いときには, 印刷 部数と同じくらいの白紙が出てしまうこともあるそうです.
     紙離れを良くするために, 息を吹き込んで空気を入れます. こうす れば白紙率はぐんと減ります*6.
     吹いた紙は, ゲスプリの右側にある給紙台にセットします.

  2. 製版

     まず, 新型機の場合は, 印刷の元原稿を, コピー機を使うときと同 じように, ゲスプリ上部の台においてフタを閉めます.

     次に, 印刷モードを決めます. 左側の操作パネルに「写真モード, 文字モード」と書かれているものがありますので, どちらかを選択し ます. 写真モードは濃淡まである程度再現しようとし, 文字モードは 白黒をはっきりつけようとします. ただ, 旧型の機械を使うときには, 文字モードは避けた方がいいでしょう.
     ちなみに, 190 号は, 78・79 ページが文字モードで残りは全て写 真モードです.
     製版モードを決めたら, 明るさや製版濃度を決めます. この設定は, 試行錯誤して体得してください. ただ, 製版は 1 回 50 円かかりま すので, なかなかそうはいかないでしょうが. (^^;)

     全ての設定が終わったら, 製版ボタンを押して下さい. 機械が勝手 に製版をしてくれます. 製版が終了すると, 自動的に一枚試し刷りが 行われます. 最初の試し刷りはインクが十分に出ないので, 印刷の位 置の確認しか出来ません. 濃淡までチェックしたいときは, 何回か試 し刷りを繰り返します. ただ, 1 枚印刷するごとに 0.5 円掛かりま すので, 見切り発車して印刷してしまう方が良いかも知れません.

    ▼原稿をセットする場所 (左が新型, 右が旧型)
     プリントステーションの旧型機では, 元原稿のセットの仕方が少し 違います. 文字の書かれている面を下向きにしてセットし, 「製版ス タート」のボタンを押すと自動的に吸い込まれて製版するようになっ ています.
     B5 二枚の原稿を並べて B4 一枚に印刷したいときには, まず「二 枚連写」なるボタンを押します. 先に右側の原稿だけセットし「製版 スタート」を押し, 「ピッピッピ」と音がなったら, 続けて左側の原 稿をセットして「製版スタート」を押します.

     なお, ときどき液晶に「ハイハンエラー」とか表示されて, 製版が ストップしてしまうことがあります (D のゲスプリは, 特に多いよう です) . このときはゲスプリの左側のフタをあけて, 中の緑色の箱に 入っている古い版をごみ箱に捨てます. 黒い部分は, 直接手で持って はいけません. 手が真っ黒になって, 作業を一時中断するハメになり ます. (^^;)

    ▼古い版をとりだすところ
  3. 印刷

     印刷枚数をセットして, 印刷スタートのボタンを押すだけです. 簡 単ですね.
     ちなみに, 僕はよく印刷スタートと製版スタートのボタンを間違え て真っ青になるのですが, 新型のゲスプリは警告メッセージを出して くれます. なんて賢いんだろう.

  4. 両面印刷

     一度印刷した紙の裏側にも印刷するときには, 原稿の向きと印 刷される向きは逆になることに注意して紙をセットしてください. 片 面だけのときは, 何も気にする必要はありません.

  5. 清算

     使い終わったら, 事務室でお金を払います.
     清算するときには, 前カバーを開けて中の数字を覚えたあと, キー カウンターを持って事務室へいき, ファイルに必要事項を書き込んで お金を払います. 領収書を書いてもらうのを忘れないようにしましょ う.

    ▼ゲスプリの操作パネル (左が新型, 右が旧型)
■終わりに
 いかがでしたか ? ゲスプリは, 大変便利な機械です. 皆さん もぜひ活用してください.



編集後記


東京大学理論科学グループ部報 TSG 第 191 号
平成 7 年 7 月 3 日 初版 第 1 刷発行

発行者 渡辺 尚貴
編集者 安田 知弘
HTML化 多賀 奈由太

発行所 東京大学理論科学グループ
〒153 東京都目黒区駒場 3-8-1
東京大学教養学部内学生会館 305
TEL 03-5454-4343


(C)Theoretical Science Group,University of Tokyo,1995
Printed in Japan.

g541119@komaba.ecc.u-tokyo.ac.jp