Tk8.0.5 Japanization Patch This file is a patch for Tk8.0.5 to be Japanized (Only for UNIX/ Windows box). See the documents included in this patch for details. To apply this patch, you should cd to the top directory of the T k8.0.5 source tree (the directory containing "README" and "licen se.terms"), and do: patch -p1 < thisFile ------------------------------------------------------------ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/Incompat80jp ./Incompat80jp *** ../../tk8.0.5/Incompat80jp Thu Jan 1 09:00:00 1970 --- ./Incompat80jp Tue Apr 6 20:03:54 1999 *************** *** 0 **** --- 1,959 ---- + tk4.xjp と tk8.0jp の非互換 + + m-hirano@sra.co.jp + + tk8.0 から、Tk のフォントメカニズムが大幅に変更されました。その一つ + として、named font の採用が挙げられます。tk8.0jp では、この named font + を拡張し、latin フォントと漢字フォントを組み合わせた named font, すな + わちコンパウンドフォントとして、単一のフォントのように扱うことにしまし + た(コンパウンドフォントのアナロジーは PostScript での複合フォントから + 拝借しました)。 + + したがって、tk4.xjp で各ウィジェットに用意されていた -kanjifont オプ + ションは、tk8.0jp では実装されていません。この実装による利点を以下に挙 + げます。 + + 1. 現状、単一のフォント内に latin 文字、漢字が存在していないの + は、Tk のサポートするプラットフォームでは X のみである。 + Windows, Mac とのスクリプトレベルでの互換を容易にするには、 + -font オプションのみで漢字、latin 文字を表示できるフォント + が指定できる方が便利である。 + + 2. tk8.0 に元来実装されている、動的なフォント属性の変更の面か + ら見ても、漢字、latin 文字それぞれのフォント属性を逐一変更 + するより、一括して行えた方が便利である。 + + 3. 各ウィジェットの日本語対応のための変更点が半減する。これは + Tix など、その他の高機能なウィジェットセットを日本語化する + 時に大変有利。 + + 反面、tk4.xjp との互換性が全くないという大きな欠点があります。 + + また、漢字変換プロトコルとして、kinput2 プロトコルの他に XIM プロト + コルを限定的にサポートしました。 + + このドキュメントは、拡張された named font の扱い方、tk4.xjp のスクリ + プトからの移行、漢字変換プロトコルのユーザカスタマイズについて解説する + ものです。特に font コマンドに関して、読者がその使用方法について充分理 + 解していることを要求しています。 + + 1. font コマンドの拡張 + + 1.1. -charset オプション + + tk8.0 オリジナルの font コマンドは、charset が iso8859 のものしか、 + 文字を表示する為のフォントとみなしませんでした(iso8859 以外はいわゆる + 記号フォントとみなす)。また、font create コマンドにも charset をオプショ + ンとして渡す仕掛けがないため、X の環境でファミリ名を "fixed" とした場 + 合には、k14 等の漢字フォントを指しているのか a14 等の latin フォントを + 指しているのか区別できません。そこで、font コマンドのオプションに + -charset を追加しました。 + + 漢字フォントで named font を生成したい場合、常に -charset + jisx0208.1983 を付けます。例えば、 + + font create @kanji -family fixed -charset jisx0208.1983 -size 13 + + とすれば、X の環境ならば k14 を実体とする @kanji という名前の named + font が生成できます。-charset オプションを指定しなかった場合はオリジナ + ル tk8.0 と同様に動きます。 + + + 1.2. -compound オプション + + 1.2.1. コンパウンドフォントの生成 + + font create コマンドに -compound オプションを指定することで、コンパ + ウンドフォントを生成します。コンパウンドフォントは常に named font とし + て生成されます。 + + ・漢字を k14 で、latin文字を a14 で表示するためのコンパウンド + フォントを SmallFont という名前で作成する + + font create SmallFont -compound { a14 k14 } + + -compound オプションへの引数には、 + + {latinフォント 漢字フォント} + + のリストを指定します(順不動)。このリストに指定されたフォントの対は、 + 生成されるコンパウンドフォントの「ディセンダントフォント」と呼ばれます。 + ディセンダントフォントとしてコンパウンドフォントを指定するとエラーにな + ります。ディセンダントフォントになり得るのは、 + + ・コンパウンドフォントでない named font. + ・ネイティブフォント + + です。 + + 生成されたコンパウンドフォントは、通常のフォント同様、tk で -font オ + プションが使える場面なら何時でも使用できます。 + + font create コマンドのオプションとして使用する場合の -compound オプ + ションは、必ず + + font create ?name? -commpound {list} + + の順序で使われなければなりません。 + + font create -compound {a14 k14} -size 15 + + もしくは + + font create fooFont -compound {a14 k14} -size 15 + + は正しいですが、 + + font create -size 15 -compound {a14 k14} + + や、 + + font create fooFont -size 15 -compound {a14 k14} + + は間違いです。エラーにはなりませんが、機能しません。 + + + 1.2.2. コンパウンドフォントの属性取得 + + -compound オプションは、属性参照モードで使用する場合にのみ、font + configure, font cget コマンドへのオプションとしても使えます。 + + 今、@normal という named font が、 + + font create @normal -famiy times -slant italic \ + -weight bold -size 15 + + によって、また、@comp というコンパウンドフォントが、 + + font create @comp -compound { @normal kanji16 } + + のように生成されているとします。 + + ここで、 + + font conf @normal + + を実行すると、 + + -family times -size 15 -weight bold -slant italic -underline 0 \ + -overstrike 0 -charset {} -pointadjust 0 -compound {} + + が返って来ます。 + + font conf @comp + + を実行すると、 + + -family times:fixed -size 15 -weight normal -slant roman \ + -underline 0 -overstrike 0 -charset iso8859:jisx0208.1983 \ + -pointadjust 1.000000 -compound {{@normal} {kanji16}} + + が返って来ます。-pointadjust オプションは、ディセンダントフォントの + ポイントサイズ比率を表します(分母が漢字フォントのポイントサイズ)。 + + font configure コマンドを使って、通常の named font をコンパウンドフォ + ントにしたり、コンパウンドフォントのディセンダントフォントを変更するこ + とは出来ません。 + + + 1.3. -copy オプション + + ネイティブフォント名を利用して named font を生成する際に font create + コマンドのオプションとして使用します。 + + コンパウンドフォントでない named font を作る時、tk8.0 の仕様では + -family オプションを指定して font create コマンドを呼ぶしか手段がありま + せんでした。 + + わざわざ k14 の named font を作るのに + + font create @kanji -family fixed -charset jisx0208.1983 -size 13 + + と書くのは繁雑なので、 + + font create @kanji -copy k14 + + と横着をするために用意したオプションです。 + + + 1.4. failsafe コマンド + + ここまでの説明で、 + + label .l -font \ + -adobe-courier-bold-o-normal--14-140-75-75-m-90-iso8859-1 + + のような、スクリプト中にコンパウンドフォント以外のフォントがエンベデッ + ドに指定されている場合などに、tk8.0jp ではまともに日本語が表示できない + んじゃないか? とお気づきになられた方がいらっしゃると思います。で、最 + 初の実装では、その通りでした ^^; + + これでは tk4.xjp とあまりに互換性がないし、特に海外から持って来た Tk + スクリプトを簡単に使用することができなくなります。 + + と、このような御指摘をうけ、もしウィジェットに指定されたフォントで日 + 本語表示が出来ないと判った場合に使用されるフェイルセーフのためのフォン + トを指定する機能を用意しました。それがこの failsafe コマンドです。 + + 例えば、 + + font failsafe k14 + + をスクリプトの最初で実行しておけば、各ウィジェットで日本語表示が正常 + に行えるフォントが指定されてなかった場合のみ、日本語の表示は k14 フォ + ントで行われます。 + + faisafe コマンドの引数にはネイティブフォントのみが指定できます。 + また、Latin フォントも指定でき、 + + font failsafe 8x16 + label .l -font kanji16 -text \ + "これも正しく表示されます。This also works." + + のようなスクリプトがあっても問題ありません。 + + font failsafe "" + + を実行すると、フェイルセーフフォントが NULL になり、フェイルセーフ機 + 能が効かなくなります。 + + 現状 UNIX 版では tkUnixInit.c のなかで、k14 をフェイルセーフフォント + として指定してあります。 + + + 1.5. コンパウンドフォントの属性の動的変更 + + 前述のように、コンパウンドフォントは named font の一種です。通常の + named font 同様、動的に属性を変更できます。変更できる属性は、アンダー + ライン、オーバーストライク、サイズ、ポイントサイズ比率の 4 つです。 + + Tcl/Tk 8.0.5jp1.5fix1 より、コンパウンドフォントの属性の動的変更によ + り、ディセンダントフォントが影響を受けることは無くなりました。 + + + 1.5.1. サイズの変更 + + font conf @comp -size 23 + + のようにして、コンパウンドフォントの大きさを変更した場合、@comp を参 + 照している全てのウィジェットが影響を受けます。前述のように、@comp のディ + センダントフォントは実際にサイズ変更されません。 + + # Tcl/Tk 8.0.5jp1.5 までは、ディセンダントフォントも実際にサイズが変 + # 更されました。なぜこのような仕様だったかというと、named font がそも + # そも「名前参照」なオブジェクトであるため、named font を参照している + # named font であるコンパウンドフォントもそれに従うべきだと考えたから + # です。が、あまりに実用的でないため、また、アンダーライン、オーバー + # ストライクの変更はディセンダントフォントに影響しない、という仕様と + # 相反するので、この仕様は廃止しました。Tcl/Tk 8.0.5jp1.5 までの仕 + # 様を利用して、「故意に、ディセンダントフォント自身の大きさをコンパ + # ウンドフォントの大きさを変える事で行っている」ようなスクリプトは、 + # 期待された動きをしないことになります。逆に、これまで、このドキュメ + # ントでは勧めていなかった、「ネイティブフォントを直接ディセンダント + # フォントに指定してコンパウンドフォントを作る」という手法には、何の + # 問題も無くなりました。 + + + 1.5.2. ポイントサイズ比率の変更 + + font conf -pointadjust 0.5 + + のようにして、漢字ディセンダフォントに対する ascii ディセンダフォン + トのポイントサイズ比率を変更できます。もし、@comp のディセンダントフォ + ントが + + {a14 k14} + + であった場合に上記の 0.5 を指定すると、@comp を使用している全ウィジェッ + トで ascii 文字を表示する場合にはファミリが fixed でポイントサイズが 7 + (k14 のポイントサイズは 13. 0.5 を掛けて四捨五入すると 7) のフォントが + 使われる事になります。当然 1.0 以上の値も指定できます。 + + ディセンダフォントのサイズが変更された場合に、コンパウンドフォントの + ポイントサイズ比率が変更される事はありません。ただし、実際の表示は、変 + 更されたサイズで行われます。要するに、コンパウンドフォントのポイントサ + イズ比率は、そのコンパウンドフォントの生成された時の比率、もしくは + -pointadjust オプションで指定された値を常に保つということです。 + + もし、ディセンダントフォントのサイズを変更し、なおかつ、コンパウンド + フォントのポイントサイズ比率も変更したい場合、スクリプト内でディセンダ + ントフォントのサイズを変更後、実際のサイズを font actual コマンド等で + 取得し、漢字フォントのサイズで ascii フォントのサイズを割算したものを、 + コンパウンドフォントのポイントサイズ比率とすれば良いでしょう。 + + + 1.5.3. アンダーライン、オーバーストライク + + コンパウンドフォントのアンダーライン、オーバーストライクの属性を変化 + させてもディセンダントフォントには影響しません。 + + + 1.6. 各ウィジェットのデフォルトフォント + + tk8.0jp の実装では各ウィジェットのデフォルトフォントは全てコンパウン + ドフォントになっています。デフォルトフォントには以下のものがあります。 + + Mincho:Helvetica-12 + Mincho:Helvetica-Bold-12 + Mincho:Courier-12 + + これらのフォントの属性を変化させると、Tk アプリケーション全体に影響 + します。この事をうまく使えば、これらのデフォルトのコンパウンドフォント + の再定義を行う事で Tk アプリケーション全体のフォントを容易に変更出来ま + す。 + + + 1.7. 移行作業 + + tk4.xjp スクリプトからの移行は、基本的に、全ての -kanjifont オプショ + ンを削除し、-font オプションで指定しているフォントを適切に定義したコン + パウンドフォントで置き換える、もしくはただ単に -kanjifont オプションを + 削除するだけで問題ありません。 + + text, entry 以外のウィジェットに、bind コマンドで直接 kinput2 とのセッ + ションを定義しているようなアプリケーションは、tk8.0jp の + $tk_library/kinput.tcl を参照して修正して下さい。 + + 海外の Tk スクリプトの日本語化に関しては、1.4. で述べた font failsafe + コマンドをスクリプトの先頭に入れておくことで、少なくとも tk4.xjp で当 + 該スクリプトを全く変更しないで実行させた場合と同等の日本語表示が行われ + ます。 + + + 1.8. サンプル + + 以下に簡単なサンプルを挙げます。 + + --------------------------------------------------------------------- + # 16ドットの courier と kanji16 をコンパウンドフォントにする。 + font create @ascii -copy \ + -adobe-courier-medium-r-normal--16-*-*-*-*-*-iso8859-1 + font create @kanji -copy kanji16 + font create @cFont -compound {@ascii @kanji} + + # @cFont を使った label を作る。 + pack [ label .l -text "123. テスト。321." -font @cFont ] + + # @cFont の大きさを 23 ポイントにし、アンダーラインを付ける。 + font conf @cFont -size 23 -underline 1 + --------------------------------------------------------------------- + + + 1.9. X リソースデータベースの扱い + + -kanjifont オプションが各ウィジェットから無くなったので、tk4.xjp で + 使用できた、 + + tkapp*kanjifont: k14 + + のような X リソースデータベースの記述は tk8.0jp では参照されません。 + そのかわり、tkDefineFont, tkDefaultFont のリソースが使用出来ます。 + + tkDefineFont リソースは X リソースデータベース内でコンパウンドフォン + トを定義するためのリソースです。 + + *tkDefineFont: small {a14 k14}, medium {8x16 kanji16} + + のように定義すると、全ての tk8.0jp アプリケーションの起動時に、 + small, medium のコンパウンドフォントが生成されます。 + + tkDefaultFont リソースは tk8.0jp アプリケーションで使用されるフォン + トを指定するためのリソースです。 + + *tkDefaultFont: small + + のように定義すると、全ての tk8.0jp アプリケーションの各ウィジェット + の default font が small になります。 + tkDefaultFont で指定したフォントがコンパウンドフォントでない場合には、 + 1.4. で述べたフェイルセーフフォントの機構が働くことになります。 + + + tkDefineFont, tkDefaultFont とも、クラス指定、ウィジェットインスタン + ス名指定には意味がありません。 + + *tkDefineFont + tkapp*tkDefineFont + *tkDefaultFont + tkapp*tkDefaultFont + + の形式でしか指定できないということです。 + + + 2. XIM プロトコルへの対応 + + 2.1 漢字変換プロトコルの指定 + + 環境変数、および X リソースデータベースのカスタマイズにより、漢字変 + 換プロトコルを kinput2, XIM の二つのうちから一つだけ選択出来るようにし + ました。同時に使うことは禁止してあります。 + + 環境変数 TK_KCPROTO を kinput2 にすると、kinput2 プロトコルが使われ + ます。xim にすると XIM プロトコルが使用されます。 + + 環境変数 TK_KCPROTO が設定されてない場合、X リソースデータベースから、 + tkKanjiConversionProtocol リソースを検索します。 + tkKanjiConversionProtocol リソースは、 + + *tkKanjiConversionProtocol: xim + tkApp*tkKanjiConversionProtocol: kinput2 + + の形で使用でき、前者は Tk8.0jp で書かれたスクリプトの default、後者 + は tkApp という任意のアプリケーションで使用されます。指定する値は、 + TK_KCPROTO と同様です。 + + もし、TK_KCPROTO も tkKanjiConversionProtocol も両方指定されない場合、 + 環境変数 XMODIFIERS が設定されていれば XIM プロトコルが使われます。 + XMODFIERS も指定されていない場合、下位互換のために kinput2 プロトコル + が選択されます。 + + 以下に、任意の Tk スクリプト tkApp で使われる漢字変換プロトコルの選 + 択のされ方を、環境変数、X リソースデータベースの強さ順でまとめておきま + す。 + + o まず環境変数 TK_KCPROTO が参照される。 + o 次に tkApp*tkKanjiConversionProtocol が参照される。 + o 次に *tkKanjiConversionProtocol が参照される。 + o 次に環境変数 XMODIFIERS の設定の有無が check され、設定され + ていると XIM が使われる。 + o 上記全てに該当しない場合、kinput2 プロトコルが使用される。 + + 2.2. 各ウィジェット毎の変換スタイルの指定 + + XIM プロトコルでは、変換サーバがサポートする、様々な変換スタイルを指 + 定できます。 + + Tk8.0jp では、現状、変換スタイルとして、 + + PreeditPosition StatusArea + …その場変換(over the spot)で、変換用編集領域、ステー + タス領域ともに Tk が管理する。Tk8.0jp が kinput2 プ + ロトコルでセッションを張る時より、若干かっこいいこと + ができる :) 現状では、違いはあまり無い ^^; + + PreeditPosition StatusNothing + …その場変換(over the spot)で、変換用編集領域は Tk が、 + ステータス領域は変換サーバが管理する。Tk8.0jp が + kinput2 プロトコルでセッションを張る時とほぼ互換。 + + PreeditArea StatusArea + …変換用編集領域、ステータス領域ともに Tk が管理する + (off the spot)。現状の実装では、ウィジェットの最下段 + に変換用編集領域として 1 行分のエリアを確保し、その + 行の一番左にステータス領域が表示されている。もう少し + 頑張れば、疑似的にその場変換風にできる ^^; + + PreeditNothing StatusNothing + …いわゆる root 変換。変換サーバが root ウインドウに変 + 換用ウィンドウを用意してくれる。Tk は文字列のやりと + り以外一切変換サーバと話さない。 + + の 4 種類をサポートしています(これは kinput2 がサポートしている変換 + スタイル全てです)。 + + 変換スタイルを指定するには、tkPreferredImStyle リソースを X リソース + データベースに指定します。例えば、Text ウィジェットの変換スタイルを指 + 定したい場合、 + + *tkPreferredImStyle(Text): {PreeditPosition StatusArea} \ + {PreeditPosition StatusNothing} + + などとしておきます。もし変換サーバが + + {PreeditPosition StatusArea} {PreeditPosition StatusNothing} + + の両方をサポートしていれば、tkPrefferdImStyle で先に指定された + {PreeditPosition StatusArea} が使用されます。もし変換サーバが + + {PreeditPosition StatusNothing} + + しかサポートしていない場合、{PreeditPosition StatusNothing} が使用さ + れることになります。tkPreferredImStyle で指定したスタイルを全く変換サー + バがサポートしていなかった場合、変換は全く行えません。 + + tkPreferredImStyle の () の中には、スタイルを指定したい Tk のウィジェッ + トクラスを指定します。もし Entry ウィジェットの変換スタイルを指定する + のであれば、 + + *tkPreferredImStyle(Entry): {PreeditPosition StatusNothing} \ + {PreeditNothing StatusNothing} + + のように指定すれば OK です。ウィジェットインスタンス指定は現状できま + せん。 + + tkKanjiConversionProtocol リソースと同様に、tkPreferredImStyle リソー + スは任意の Tk スクリプト tkApp 毎に指定することももちろん可能です。 + + tkApp*tkPreferredImStyle(Entry): {PreeditPosition StatusNothing} \ + {PreeditNothing StatusNothing} + + のように書くと、tkApp の Entry ウィジェットの変換スタイルが指定でき + ます。 + + 2.3. imconfigure コマンドについて + + XIM プロトコルに対応するために、Tk8.0 に新たに imconfigure コマンド + を追加しました。imconfigure コマンドについて少し説明しておきます。 + + Syntax: + imconfigure path ?option args? ?option args? ... + + option には、 + + -status + -supportedStyle + -style + -spot + -preeditArea + -statusArea + -preferredStatusArea + -font + -foreground + -backgrpund + + が指定できます。option が全く指定されて無い場合、path の現在の状態を + 全て返します。例えば、 + + -status started -supportedStyle {{PreeditPosition StatusArea} + {PreeditPosition StatusNothing} {PreeditArea StatusArea} + {PreeditNothing StatusNothing}} -style {PreeditNothing StatusNothing} \ + -spot {} -preeditArea {} -statusArea {} -preferredStatusArea {} \ + -font Mincho:Courier-12 + + のような文字列が返って来ます。 + + + o -status (引数なし:情報取得のみ) + + 変換サーバとセッションを張る為のコンテキスト(AKA XIC. See also X11 + documents)が生成されているか否かを返します。コンテキストを生成するには、- + style オプション(およびそのスタイルの初期化に必ず必要なその他のオプショ + ン)を指定して imconfigure コマンドを呼び出します。もし、コンテキストが + 生成されていなかった場合、"never" が返ります。コンテキストが生成されて + いたら "started" が返ります。 + + o -supportedStyle (引数なし:情報取得のみ) + + 変換サーバがサポートする変換スタイルのリストを返します。当然書換えら + れません。 + + o -style {style} + + {style} に変換スタイルを指定します。指定できるのは、-supportedStyle + オプションで返って来たリストのうちの一つです。{style} に何も指定しない + 場合、現在の変換スタイルを返します。-status オプションが "never" を返 + す状態では、-style オプションは {} を返します。 + もし、-status オプションが "started" を返す状態で -style オプション + に違う値を指定して imconfigure コマンドを呼び出した場合、現在のコンテ + キストは破壊され、新しいコンテキストが再生成されます。変換スタイルを動 + 的に変えたい場合にのみ、このような使い方をすべきです。 + + o -spot {x y} + + 変換用編集領域内での編集位置を {x y} にそれぞれ X 座標、Y 座標で指定 + します(変換用編集領域の x, y を原点とする)。-style オプションで指定し + た変換スタイルに、PreeditArea, PreeditPosition のどちらかが指定されて + ないと無意味、もしくは imconfigure コマンドが失敗します。{x y} を指定 + しない場合、現在の編集位置が返ります。 + + o -preeditArea {x y w h} + + 変換用編集領域のジオメトリを {x y w h} にそれぞれ X 座標、Y 座標、幅、 + 高さを指定します(path で指定したウィジェットの x, y を原点とする)。- + style オプションで指定した変換スタイルに PreeditArea, PreeditPosition + のどちらかが指定されてないと無意味、もしくは imconfigure コマンドが失 + 敗します。{x y w h} を指定しない場合、現在の変換用編集領域のジオメトリ + が返ります。 + + o -statusArea {x y w h} + + ステータス領域のジオメトリを {x y w h} にそれぞれ X 座標、Y 座標、幅、 + 高さを指定します(path で指定したウィジェットの x, y を原点とする。- + style オプションで指定した変換スタイルに StatusArea が指定されてないと + 無意味、もしくは imconfigure コマンドが失敗します。{x y w h} を指定し + ない場合、現在のステータス領域のジオメトリが返ります。 + + + o -preferredStatusArea (引数なし:情報取得のみ) + + 変換サーバが推薦する、ステータス領域のジオメトリを返します。-style + オプションで指定した変換スタイルに StatusArea が指定されてないと無意味、 + もしくは imconfigure コマンドが失敗します。 + + o -font font + + 変換用編集領域、ステータス領域での文字の表示に使用されるフォントを + font に指定します。font を指定しない場合、現在のフォントが返ります。 + + o -foreground color + + 変換用編集領域、ステータス領域の foreground color を color に指定し + ます。color を指定しない場合、現在の foreground color が戻ります。 + + o -background color + + 変換用編集領域、ステータス領域の background color を color に指定し + ます。color を指定しない場合、現在の background color が戻ります。 + + + 2.3.1 imconfigure コマンドの使用例 + + $tk_library/xim.tcl を参照してください。tkConfigIm プロシジャが肝で + す。 + + + 2.4. XIM 使用上の制限 + + 2.4.1. 変換文字列長は 1024 バイトである + + 現在の最新版と思われる X11R6.3 fix-02, XFree86 3.3.2 でも、 + XmbLookupString() にバグがあり、変換サーバとの通信において、可変長バッ + ファが使えません。Tk8.0jp に、XmbLookupString() のみを fix したものを + 同梱することも考えましたが、各バージョンの Xlib と整合をとるのがめんど + くさくなったので ^^; 止めてます(XFree86 3.3.[12] ではとりあえず可変長 + バッファが使えるようにしたものはある)。 + で、現状、実用上困らない範囲として、固定長バッファをスタック内に + 1024 バイト確保しています(SIJS, EUC で喋ると 512 文字)。変換結果がこれ + より長くなると、1024 バイト以降は捨てられます。 + もし、「俺の XmbLookupString() はそんなバグを持ってないはずだ」と自 + 信がある方は、generic/tkBind.c を、-DUSE_FIXED_XMBLOOKUPSTR をつけてコ + ンパイルしてみてください。これで 40 バイト以上の変換結果が得られたら、 + その X のバージョンを是非おしえてください。 + + 2.4.2 R5 ベースの Xlib で動くか? + + 動くはずです。ただ、私としては、XFree86 なり X11R6.3 なり X11R6.4 な + りをお使いになることを奨めます :) + + 現状、SunOS 5.x i386 の xlib (/usr/openwin/lib/libX11.*) で動く事を + 確認しています。ただし、SunOS 5.x 付属の XIM プロトコルベースの変換サー + バである htt との通信は、SunOS 5.x 付属の X サーバが、tk が + XSetICValues() を発行した時点で落ちるため、未確認です。htt を SunOS + 5.x 付属の X サーバ以外で動かすことが容易であれば、テストも可能なので + すが、これがなかなか成功してくれないので困っています。 + + 2.4.3 on the spot モードは未対応 + + 変換スタイル (XIMPreeditCallbacks|XIMStatusCallbacks)、いわゆる on + the spot 変換には未対応です。いつかその気になったら(当然これをサポート + する変換サーバが必要ですが)、やるかも知れません ^^; + + + 3. その他 + + 3.1. configure の変更 + + XIM プロトコルに対応するためには、X の設定を正確に知る必要があります。 + 特に -DX_LOCALE, -DX_WCHAR の有無が大変重要になります。そこで、 + configure スクリプトで imake 環境を check して、imake で使用される C + プリプロセッサオプションを参照するように変更しました。これに伴い、これ + までの Makefile.in を直接編集することでコンパイル環境を変更する方式か + ら configure に --enable-*/--disable-* オプションを指定する方式に変更 + しました。使用可能なオプションは、configure --help で表示されます。以 + 下に日本語関係のオプションを挙げておきます。 + + --enable-kanji 日本語化機能を使用可能にする(デフォルト)。 + + --enable-kinput2 kinput2 プロトコルを使用可能にする(デフォ + ルト)。 + + --enable-ximImprove まともな XIM プロトコルサポートを使用可能 + にする(デフォルト)。 + + --enable-xlfdCheck 間違った XLFD 名のチェック機能を有効にする + (デフォルト)。3.3 参照。 + + --enable-xlibHack XFree86 3.3.2 を使っている場合にのみ指定で + きます。指定すると、XListFonts(), + XLoadQueryFont() を Tk の独自ルーチンに置 + き換える事で、 + + ・ListFonts protocol の発行をなるべく + 抑制する。Tk の立ち上がり時にその X サー + バで使用可能なフォント全てを調べ、以降 + まずそのリストを検索することで代用。も + し見つからなかった場合(Scalable font + 等)にのみ実際に ListFonts を発行する。 + + ・同じ名前(正式 XLFD 名、アリアス全て + を含む)を持つフォントは 1 度しか + LoadFont されなくなる。 + + ・XCreateFontSet() が上記 2 つの独自ルー + チンを参照するようになる。 + + --disable-kanji を指定した場合の tk8.0jp の動作は保証しません :)。 + + 3.2. kinput2 プロトコルでの変換開始キーの指定 + + これまでやろうやろうと思っていて全然やってなかったのですが ^^;, XIM + プロトコルで変換スタイルを指定できるようにしたついでに、kinput2 プロト + コル使用時の変換開始キー、各ウィジェットの変換スタイルを X リソースデー + タベースで指定できるようにしました。 + + 3.2.1 変換開始キーの指定 + + tkKinputStartKeys リソースを、例えば以下のように指定します。 + + *tkKinputStartKeys: Control-backslash \ + + + キーシーケンスは Tk の bind コマンドに使用されるものです。<> で括ら + れていない場合、自動的に <> で括られます。くどいですが、任意の Tk スク + リプト tkApp 毎に変換開始キーを指定するころも可能です。 + + 3.2.2 各ウィジェットの変換スタイル + + tkKinputStyle リソースで指定します。 + + *tkKinputStyle(Text): over + *tkKinputStyle(Entry): root + + のように、() の中には Tk のウィジェットクラス(Text, Entry)を指定しま + す。値は over, root のどちらかで、over がその場変換、root が root 変換 + を示します。 + + + 3.3. X-TT 拡張された X サーバへの対応 + + X-TT サーバ(X TrueType server。 + http://cclub.cc.tut.ac.jp/~Ego/unix/xtt.html参照)の xtt05-fix1 を使用 + している場合(未確認ですが、これより古いバージョンにも多分該当します)、 + XListFonts() して XGetAtomName() することで得られる XLFD のフォーマッ + トが間違っており、TrueType フォントを tk8.0 上で named font として使用 + できませんでした(ネイティブフォントとして failsafe フォントなどに使用 + することは可能)。 + + # xtt06 がリリースされました。が、まだ確かめてません ^^; + + たかが XLFD の間違いくらいで使えないのは大変悲しいし、同じようにかな + り厳しく XLFD のパーズを行っていると思われる Netscape では問題無く使え + ているのが比較対象にされてシャクなので ^^;、日本語化には基本的に無関係 + な XLFD のパーズルーチンに手を入れました。ただし、X-TT サーバが対応し + た場合、および X-TT でない X サーバを使っている場合には単なる冗長な + XLFD チェックルーチンにしかなりませんが、現状これをデフォルトにしてあ + ります。これを止めたい場合、--disabel-xlfdCheck を指定して configure + を実行すれば良いです。 + + tk4.xjp との非互換というわけではありませんが、tk4.xjp では問題無く + X-TT サーバ上で TrueType が使えるのでここに記しました。 + + + 3.4 canvas ウィジェットでの PostScript 出力時のフォント指定 + + canvas ウィジェットの postscript コマンドを使用する際、-fontmap オプ + ションを指定することで canvas ウィジェット内で使用されているフォント名 + と PostScript で使用するフォント名を対応付けることが出来ます。 + + tk8.0jp では -fontmap オプションに渡す配列のフォーマットが拡張されて + おり、tk8.0 で + + set fontMap(myFont) {PSFont pointSize} + + と書くところを、 + + set fontMap(myFont) {{PSFont PSKanjiFont} pointSize} + + のように書く事で、canvas ウィジェット内で myFont というフォントで描 + 画された文字列を PostScript 出力する時には、ascii 文字は PSFont、漢字 + は PSKanjiFont で出力する、という指定が可能になっています。pointSize + には PostScript でのポイント数を指定します。もし myFont が 12 ポイント + であれば、pointSize にも 12 を指定するのが良いでしょう。 + + -fontmap オプションを指定する場合、通常後者のフォーマットで構成され + た配列を渡す事をお推めします。 + + tk8.0jp で前者の指定をした場合、myFont の形式に依存して PostScript + フォントが決定されます。以下に一応それをまとめます。 + + o myFont が ascii フォントだった場合、ascii 文字の出力に + PSFont が使用され、漢字の出力は常に Ryumin-Light-EUC-H が使 + 用される。 + + o myFont が漢字フォントだった場合、ascii 文字の出力には常に + Courier が使用され、漢字の出力に PSFont が使用される。もし + PSFont が ascii 文字分のグリフしか持たないフォントであった場 + 合、漢字が含まれた文字列は正常に印刷されない。 + + o myFont がコンパウンドフォントであった場合、常にエラーとなる。 + + -fontmap オプションを指定しない場合、canvas ウィジェット内で myFont + というフォントで描画された文字列を PostScript 出力する時には、ウィンド + ウへの描画同様、myFont の形式とファイルセーフフォントの指定に応じて + PostScript フォントが決定されます。つまり、canvas ウィジェット内で正常 + に ascii 文字と漢字が表示出来ているなら、少なくとも文字化けしないで印 + 刷できるということです。 + + -fontmap オプションを指定しない場合、現状、UNIX 版では、漢字フォント + は常に Ryumin-Light-EUC-H を使用します。 + + tk8.0jp は PostScript を常に EUC で出力します。したがって、漢字を表 + 示するための日本語フォントは、常に EUC フォントを選択する必要がありま + す。 + + -fontmap オプションの使用例をあげておきます。この例は、canvas ウィジェッ + ト内の text を Helvetica-Bold と GothicBBB-Medium-EUC-H を使用して + PostScript に落とします。 + + canvas .c + pack .c + set t [.c create text 100 100 -text "Helvetica とゴシックBBB"] + set f [.c itemcget $t -font] + set fontMap($f) {{Helvetica-Bold GothicBBB-Medium-EUC-H} 12} + set ps [.c postscript -fontmap fontMap] + + + 3.5. selection, clipboard コマンドでの target Atom と type Atom + + 3.5.1. selection の取得 + + Tcl/Tk 8.0.4jp1.3 までは、tk4.xjp 同様、Tk が他のクライアントに + SelectionRequest を送る場合(早い話が Cut & Paste することで、Tk 的には、 + selection get コマンドを使用)、デフォルトの target Atom (selection get + コマンドの -type のオプションに指定する文字列)に COMPOUND_TEXT を使用 + していました。また、COMPOUND_TEXT でのセレクション取得に失敗しても、 + target Atom の設定を変えて再要求することをしませんでした。このため、 + target Atom として STRING しか処理できないクライアントからは Cut & + Paste で Tk 側に値をもらって来る事が簡単に出来ませんでした(自分で Text + ウィジェットのキーバインドを変え、失敗したら STRING Atom で再要求、等 + する必要があった)。 + + Tcl/Tk 8.0.4jp1.4a から、この仕様を変え、デフォルトで、 + + a. 最初は TEXT で要求。 + b. a. が失敗したら COMPOUND_TEXT で要求。 + c. b. も失敗したら STRING で要求。 + d. 失敗。 + + のようにしました。当然ですが、selection get コマンドの -type オプショ + ンは今まで通り使用できます。 + + 3.5.2. clipboard append コマンドによる selection の設定 + + 3.5.1. の逆に、clipboard append コマンドでクリップボードに値を設定す + る場合も、Tcl/Tk 8.0.4jp1.4a から以前の仕様と変えました。以前の + clipboard append コマンドのデフォルト(-format, -type オプションを指定 + しない場合)では、target Atom (-type オプションの値)として + COMPOUND_TEXT, type Atom (-format オプションの値)として COMPOUND_TEXT + を使用していました。この場合、COMPOUND_TEXT で要求してくれるクライアン + ト以外にはクリップボードの内容を渡せませんでした(当然 -format, -type + オプションを使用すれば可能である)。 + + Tcl/Tk 8.0.4jp1.4a からは、デフォルトで、 + + a. 足したい内容に漢字が含まれる場合 + + i. target:TEXT type:COMPOUND_TEXT + ii. target:COMPOUND_TEXT type:COMPOUND_TEXT + iii. target:STRING type:STRING + + b. 足したい内容が全部 ascii 文字の場合 + + i. target:TEXT type:STRING + ii. target:STRING type:STRING + + のように、複数タイプの要求に答えられるようにしました。a.iii. の場合、 + クリップボード内の漢字コードは Tcl の internalCode になっています。し + たがって、a. の場合に STRING target で要求された時は、要求したクライア + ントも internalCode の漢字コードを知っていなければ文字化けすることにな + ります。 + + ちなみに、entry, text ウィジェット等の、最初から文字列しか扱わないと + 判っているウィジェットの Cut & Paste では、これと同様な機能が以前から、 + そのウィジェット自身の機能として実現されていました(要するに、selection + コマンドや clipboard コマンドを使って selection handler 等をスクリプト + レベルで実装しなくても良い、ということ)。それを意味的に clipboard コマ + ンドのデフォルトにも適用したわけです。 + + + 4. Text ウィジェットでの禁則処理 + + tk4.xjp での禁則処理は、フォント毎にハードコーディングされた禁則文字 + テーブルを用いて禁則処理を行っていました。また、tk8.0.4jp 1.4 までの + tk8.0jp は、禁則処理を完全に無視してました ^^; (フォント毎に禁則文字テー + ブルを作ってはいたけど、誰も参照してなかった ^^;) + + tk8.0.5jp 1.5 より、日本語禁則処理のための kinsoku コマンドを導入し + ました。kinsoku コマンドを用いる事で、自由に行頭禁則文字、行末禁則文字 + を指定できます。 + + 4.1. kinsoku コマンドの仕様 + + kinsoku コマンドは、以下の書式で用います。 + + kinsoku show|add|delete begin|end|both ?文字 文字 ...? + + kinsoku show コマンドは、現在の禁則文字データベースを表示するのに用 + います。2 番目の引数には begin(行頭禁則), end(行末禁則), both(行頭行末 + 禁則) のいずれかを指定します。 + + kinsoku add コマンドは、禁則文字データベースへの禁則文字の登録に使用 + します。2 番目の引数には begin, end, both のいずれかを指定します。登 + 録する禁則文字は、ただ単に空白で区切って 1 個以上指定します。リストで + はありません。 + + kinsoku delete コマンドは、禁則文字データベースから指定した禁則文字 + を取り除くのに使用します。くどいですが 2 番目の引数には begin, end, + both のいずれかを指定します。取り除く禁則文字は、ただ単に空白で区切っ + て 1 個以上指定します。リストではありません。指定した禁則文字が、禁則 + 文字データベースにない場合、単に無視されます。 + + 例 1: '.', ',' を行頭禁則文字に設定。 + + kinsoku add begin "." "," + + 例 2: '@' を行頭行末禁則文字に設定。 + + kinsoku add both "@" + + both の指定は、 + + kinsoku add end ... + kinsoku add begin ... + + を発行したのと等価。 + + + kinsoku コマンドで制御する禁則文字は、Text ウィジェットの、-wrap オ + プションが word の時にのみ作用します。また、禁則文字データベースは、プ + ロセスに一つです。Text ウィジェットの属性ではありません。 + + また、禁則処理が働くのは、指定した禁則文字の「前後に」漢字キャラクタ + が存在する場合のみです。例えば、'.' が禁則文字データベースにあっても、 + + + a.aaaaa.dddd.ccccc + + のような文字列は英語として扱われ、日本語禁則処理の対象にはなりません。 + そもそも英文には禁則文字の概念は必要なく、word wrap で片付くからです。 + 上記文字列は空白が全く含まれてないので、英文としては 1 単語として扱わ + れ、'.' が日本語禁則文字であっても処理の対象と見なさないからです。 + + 詰めによる禁則は行いません ^^; 全部次の行への追い出しです ^^; + + デフォルトの禁則文字の設定は、$tk_library/kinsoku.tcl で行われていま + す。現状以下の通りです。 + + 行頭禁則: + + "!" ")" "," "." "?" "]" "、" "。" "?" "!" ")" "〕" "]" + "」" "』" "】" + + 行末禁則: + + "(" "[" "(" "〔" "[" "「" "『" "【" + + + 4.2. $tk_library/kinsoku.tcl の編集時の注意 + + 通常、$tk_library/kinsoku.tcl を編集しなおさず、各スクリプト内で + kinsoku コマンドを用いて禁則文字データベースを変更して欲しいのですが、 + 「どーしてもデフォルトの設定を変えたい」という方は、以下に注意して変更 + してください。 + + $tk_library/kinsoku.tcl は、JIS コードで書かれています。これは、立ち + 上げ時に、どんな internal code でもコードの自動判別を成功させるためで + す。EUC や SJIS で書くと、コードの自動判別を誤る可能性があるので、故意 + にこうしています。Windows など、ほぼ間違い無く SJIS が使われる環境では + SJIS で書いても良いかも知れませんが、UNIX のように個人の設定で立ち上げ + 時の internal code が違うことが当り前の環境では、JIS で記述するように + してください。 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/README.JP ./README.JP *** ../../tk8.0.5/README.JP Thu Jan 1 09:00:00 1970 --- ./README.JP Fri Sep 11 19:31:29 1998 *************** *** 0 **** --- 1,101 ---- + The Japanization of Tk + + by Yoshiyuki Nishinaka (nisinaka@sra.co.jp) + Makoto Ishisone (ishisone@sra.co.jp) + Motonori Hirano (m-hirano@sra.co.jp) ... 8.0 support. + Software Research Associates, Inc. + + + 1. Introduction + --------------- + + Here we provide a patch kit for enabling Tk to handle Japanese characters + (kanji). + + The patch kit contains: + + + Modifications to the Tk8.0 source code + - Tk widgets are modified to display, input and cut&paste kanji + string. + + A document describing the incompatibility from the Tk4.xjp. + (Only Japanese versions is available. sorry for that) + + The Japanization is self-contained except XIM support -- to enable XIM + (X Imput Method) support, You should use at least X11R5 (X11R6.3 later + is prefferd. XFree86 3.3.2 is the best). Furthermore, the X11 library + must be "well-configured". If your operating system doesn't have + setlocale(3) that can handle proper locale for kanji (like + "Ja_JP.eucJP", "japanese", etc..), the X11 library must be + configured/compiled with "-DX_LOCALE" cpp flag. Even if you are not + sure about this, don't worry :) see 3. to disable XIM feature. + + + 2. Some selected features + ------------------------- + + The Japanization includes the following features: + + + Every Tk widget can handle kanji strings which can contain both kanji + (Shift-JIS, JIS, EUC) and ascii encoded characters. + + It conforms to the ICCCM for string encoding (COMPOUND_TEXT) on data + exchange so that it can exchange data with other applications which also + conform to the ICCCM. + + Users are allowed to input kanji strings via kinput2 (The popular input + method which is included in the X11's user contributed + software). Also as the input methods, user can use XIM protocol. The user + may choose an input style for each widget from: + PreeditPosition StatusArea + PreeditPosition StatusNothing ... AKA "over the spot" + PreeditArea StatusArea ... AKA "off the spot" + PreeditNothing StatusNothing ... AKA "root conversion" + Callback conversion is not supported. + + Canvas widgets can also generate kanji PostScript(tm) outputs + (including CID encording fonts support). + + Additional named fonts creation method to compound the iso8859 + font and the jisx0208 font. + + Please refer to the document for details. + + + 3. Compile & Installation + ------------------------- + + You may need to specify the Tcl directory when you run `configure' script. I + usually rename a Japanized Tcl source directory as `tcl8.0jp'. In this case, + you have to run `configure' script as follows: + + % ./configure --with-tcl=../../tcl8.0jp/unix + + The 'configure' script have following japanized specific options: + + --enable-kanji enable kanji features('enable' default) + --enable-kinput2 enable kinput2 protocol('enable' default) + --enable-ximImprove enable better XIM protocol support('enable' default) + --enable-xlfdCheck enable invalid XLFD name checking feature('enable' default) + --enable-xlibHack replace some functions in Xlib for font cache('disable' default) + ... If you are using XFree86 3.3.2 you can use this option. + + Some of the library files (usually installed in "/usr/local/lib/tk") are + modified for the Japanization. Since these modifications do not affect + anything about the behavior of the original Tk, any scripts for the original + version can also work with the libraries of this Japanized Tk. + + There is an major incompatibility between tk4.xjp and tk8.0jp. For + more detail, see "Incompat80jp" in this directory. + + + 4. Test + ------- + + We provide a test suite 'tests/fontjp.test' for the Japanized Tk. + + + 5. Bug report + ------------- + + Please report comments & bugs via e-mail to: + + tcl-jp-bugs@sra.co.jp + + Please don't forget to include a brief description of your environment such as + your machine type, OS version or X library version. diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/TkWinjp.txt ./TkWinjp.txt *** ../../tk8.0.5/TkWinjp.txt Thu Jan 1 09:00:00 1970 --- ./TkWinjp.txt Sat Apr 10 05:06:52 1999 *************** *** 0 **** --- 1,67 ---- + Tcl/Tk 8.0.5 日本語化パッチにおける Windows 対応部分について + + by Atsushi Nemoto (anemo@mba.sphere.ne.jp) + + * コンパイル + + コンパイルの方法はオリジナルと同じです。ただしソースディレクトリの名前 + は tcl8.0.5jp, tk8.0.5jp としておく必要があります。コンパイルは + VC++5.0 (makefile.vc)でのみ確認しました。makefile.bc も変更してありま + すが、正しく動作するかどうかは未確認です。 + + NODEBUG=0 でコンパイルすると警告が出て make に失敗するかもしれません。 + その場合はコンパイルフラグから -WX オプション(警告をエラーとして扱う) + を外してください。 + + # VC++ 4.0 には、tk8.0.5jp/win/tkWinX.c が参照している zmouse.h が付属 + # していないようなので、VC++ のバージョンを見て上記ヘッダを参照するか + # しないか決めています。 + + * Win32版に固有の変更、注意点 + + - 参照するレジストリのキーはオリジナルと同じです。 + + - ライブラリはインストールディレクトリの lib\tcl8.0jp および + lib\tk8.0jp を参照します。 + + - 実行ファイル、DLL の名前には "jp" がつきます(ex. wish80jp.exe)。 + + - コンパウンドフォントが使用可能です。UNIX 版と同様に ascii フォント + と kanji フォントを使い分けてテキストを描画します。 + + - ネイティブフォントに "defaultgui" を追加してあります。これは日本語 + Windows では 9 ポイントの "MS Pゴシック" フォントになります。 + + - 全てのウィジェットのデフォルトフォントは "defaultgui" です。 + + - failsafe コマンドで指定できるのはネイティブフォント(system, + oemfixed, defaultgui, etc.)のみです。デフォルトの failsafe フォント + は "defaultgui" になっています。 + + - Canvas の Postscript 出力では、名前に "ゴシック" が含まれているフォ + ントを使っている漢字に対しては GothicBBB-Medium-EUC-H 、それ以外の + 漢字では Ryumin-Light-EUC-H を使用します。 + + - IME による漢字の入力が可能です。漢字を入力する場合、フォーカスのあ + るウィジェットが entry または text なら挿入カーソルのある位置、それ + 以外ではウィジェットの下端に IME 編集ウィンドウが表示されます。また + entry および text ではそのウィジェットのフォントの大きさにあわせて + IME のフォントの大きさが設定されます。コンパイルオプション + IME_AWARE を定義しない場合、これらの IME の制御は行われません(IME + による入力そのものは可能です)。IME_AWARE はデフォルトで定義されてい + ます。 + + - ウィンドウタイトル、ファイル名、レジストリキーなどに漢字を使用する + ことが可能です。漢字コードに関しては、Tk は Win32 API に渡す文字列 + が常に SJIS になるように変換しますが、Tcl はこのような変換を行いま + せん。つまり、ウィンドウタイトルやフォント名等に使用する文字列は自 + 動的に SJIS に変換されますがファイル名やレジストリキー等の指定に使 + 用する文字列は変換されません。内部コードを SJIS 以外にする場合や + SJIS 以外のデータファイルから読み込んだ文字列を使用したりする場合に + は注意してください。 + + - jp1.5 から導入された日本語の禁則処理は Windows 版でも使用可能です。 + ただし、Text 以外のウィジェットでは、漢字と ASCII 文字との間では禁 + 則ルールが無視される、という制限があります。例えば '。', '.' が行頭 + 禁則文字である場合、"あ。" は 'あ' と '。' の間で改行されませんが、 + "あ." は 'あ' と '.' の間で改行されてしまいます。 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/changes.JP ./changes.JP *** ../../tk8.0.5/changes.JP Thu Jan 1 09:00:00 1970 --- ./changes.JP Sat Apr 10 05:06:52 1999 *************** *** 0 **** --- 1,368 ---- + Release tk8.0.5jp1.5fix1 Apr 10, 1999 + + (new contents) Now this kit includes Japanized version of the + "Widget tour". Special thanks to Mr. Atsushi Nemoto. + + (bug fix) Stopping direct-concatenation of $tk_library and file + name to be sourced for operand of source command in tk.tcl. + (UNIX/Win) + + (bug fix) Setting failsafe font caused memory leaks. (UNIX/Win) + + (feature change) Postions of underline and overstrike get better + now. (UNIX) + + (bug fix) Initiating kanji conversion session between kinput2 via + kinput protocol caused core dump on 64 bit word machines. + + (feature change) Now changing attributes of a compound font + doesn't affect attributites of descendant fonts of the compound + font. (UNIX/Win) (POTENTIAL INCOMPATIBILITY) + + (feature change) Now Tk checks type of returned selection to + determine the returnd type is REALLY COMPOUND_TEXT. (UNIX) + + (new feature) Now kinsoku management works on any widgets that has + capability to display text. (UNIX/Win) + + (bug fix) Line-end kinsoku management didn't work + properly. (UNIX/Win) + + Release tk8.0.5jp1.5 Mar 15, 1999 + + Confidential release tk8.0.5jp 1.5a Mar 12, 1999 + + (new release) Modified for tk8.0.5. + + (feature change) For compatibility to original, Now tk DOESN'T + refer DPI information to find a font. Thus, some font test must be + failed as same as original. (UNIX) + (POTENTIAL INCOMAPTIBILITY) + + (bug fix) Avoiding wired behavior when using /usr/openwin/bin/Xsun + on Solaris 2.x. This X server ALSO returns BOGUS XLFD via + XGetAtomName(XGetFontProperty(XA_FONT)). (UNIX) + + (bug fix) Related avobe, now tk finds a font property name SOMEHOW + EVEN IF XGetFontProperty(XA_FONT) for the font fails. (UNIX) + (POTENTIAL INCOMAPTIBILITY) + + (performance tuning) Text drawing by any widgets get little bit + faster (approximately 5%). In some case, It is faster than + original :^) (UNIX) + + (new feature) Now tk can "kinsoku" management in Text widget. If a + user specify -wrap word mode, Text widget refers kinsoku character + database managed by kinsoku command. The user can add/delete/show + kinsoku character database. (UNIX/Win) + + Release tk8.0.4jp1.4 Feb 12, 1999 + + (new release) Many bug fixes. And from now the Windows version is + called as stable 8.0jp release. + + (new feature) Now canvas PS output can handle hankaku + kana. (UNIX/Win) + + (feature change) 'Cut & Paste' and clipboard handling robustness + is increased. (UNIX/Win) + + (bug fix) Menu accelerator didn't work at all if the menu have + kanji string entries. (UNIX/Win) + + (bug fix) entry/text binding that use clipboard/selection lost + data containing kanji strings. (UNIX/Win) + + (bug fix) Even if a TEXT selection conversion request can be + accepted successfuly, Tk returned an answer as TEXT. According + to ICCCM, reply for TEXT coversion request must be one of + STRING/COMPOUND_TEXT/C_STRING. (UNIX) + + Confidential release tk8.0.4jp1.4a Jan 31, 1999 + + (new feature) Compound font support in Windows. (Win) + + (bug fix) Now canvas refer failsafe font when PostScript + generation. (UNIX/Win) + + (bug fix) Full overhauling of failsafe font. Now failsafe font can + be specified by display using "font failsafe ?-displayof? ?path? + ?nativefont?" command. (UNIX/Win) + + (bug fix) Key board focus was completely lost when a window using + XIM is taken the focus by other toplevel(s). (UNIX) + + Release tk8.0.4jp1.3 Dec 18, 1998 + + (new release) Windows platform is still in beta state, but it + seems to work well. + + Confidential Release tk8.0.4jp1.3a Dec 5, 1998 + + (new feature) Merging Windows platform patch contributed by + Mr. Atsushi Nemoto. Thanks a LOT! Cool man! + + (bug fix) Completely forgot to hard code prolog.ps into + tkCanvPs.c. And replace eucfont routine to fixeucfont-1.2, + invented by Mr. Norio Katayama. Thanks a LOT :) + + Release tcl8.0.4jp1.2 Nov 28, 1998 + + (new release) Modified for Tk8.0.4 + + Release tk8.0.3jp1.1-fix1 Oct 16, 1998 + + (bug fix) Entry binding didn't work properly in XIM session. + + (bug fix) Widget path name that have kanji could not be parsed + when internal kanji code is JIS. + + Release tk8.0.3jp1.1 Sep 11, 1998 + + (new release) Modified for Tk8.0.3 + + (bug fix) MANY fixes around XIM. Thanks for everyone who send me + bug reports! + + (feature change) Font loading algorithm is changed. Now foundry + information of XLFD can be specified when named font + creation. font command has "-foundry" option. If the font foundry + is specified, and pointsize is not zero, Tk tries to load the font + as exactly as the XLFD pattern specified. In this case, Tk also + use DPI information. This is efficient when using rather slow, + legacy X server(means for X server that has slow + LoadFonts/ListFonts protocol handling routine). + (No problem when 'make test', but mayhaps has POTENTIAL + INCOMPATIBILITY, depend on X server or X Font search path) + + (new feature) Font cache. To find a font, Now tk8.0jp doesn't call + XListFonts() as frequently as older version is doing. Furthermore, + fonts loaded by font command are cached for very next text + drawing. These cached fonts can be unloaded by calling "font + cache clear" command. Furthermore, by configure option, + XLoadQueryFont() and XListFonts() will be replaced to Tk's + internal function that referrence cached font. This improve + performance and resource usage of XCreateFontSet(), helpfull + for XIM session. This replacement is ONLY available for XFree86 3.3.x. + + Release tk8.0p2jp1.1b0 Jul 16, 1998 + + (bug fix) Tk_WTextWidth() was called with non-terminated wchar + string and -1 length in tkUnixMenu.c. + + (bug fix) TK_CONFIG_END had a different definition from the + original, again. + + Confidential release tk8.0p2jp1.1b0 Jun 13, 1998 + + (new feature) better XIM support. Tk8.0jp now can use XIM + protocol with various input style (POTENTIAL INCOMPATIBILITY). + + Release tk8.0p2jp1.0 May 18, 1998 + + (bug fix) Adding strict status checking for kinput2 session to + avoid error when re-creation of same named widget. + + (bug fix) *tkDefaultFont resource in X resource database didn't + work at all. + + (support) Adding X-TT server support code to avoid XLFD bug in the + server. + + Release tk8.0p2jpb3 Feb 23, 1998 + + (feature change) Now font option "-pointadjust" specify (ascii + point size)/(kanji point size). + + (bug fix) Descendant ascii font of a compound font was always + resized to descendant kanji font of the compound font. + + Release tk8.0p2jpb2 Jan 23, 1998 + + (bug fix) Some keyboard binds didn't work correctly in kinput2 + session. + + (bug fix) kanjiInput command didn't pass the font attribute to + kinput2. + + (bug fix) "font configure" command for compound font doesn't work + correctly. + + (bug fix) "font create" command can't handle options after + "-compound" option. + + (feature change) "font create" command now can create named fonts + starting with "-" (POTENTIAL INCOMPATIBILITY). + + (new feature) "font failsafe" command was added for 4.xjp backword + compatibility. + + (new feature) "tkDefineFont" and "tkDefaultFont" resource in X + resource database are referenced at start up. + + Release tk8.0p2jpb1 Dec 25, 1997 + + (bug fix) Fixed core dump bug when initiating kinput2 session on + Solaris 2.x. + + (bug fix) Fixed core dump bug when getting X server default font. + + Release tk8.0p2jpb0 Nov 28, 1997 + + (new release) Modified for Tk8.0p2. + + Release tk8.0p1jpb0 Nov 21, 1997 + + (new release) Modified for Tk8.0p1. + + Confidential Release tk8.0jpa0 Aug 22, 1997 + + (new release) Modified for the Tk8.0. + + Confidential Release tk8.0b1jp Jun 25, 1997 + + (new release) Modified for the Tk8.0b1. + + (feature change) No more -kanjifont option (MAJOR INCOMPATIBILITY). + + (new feature) Supporting the compound font mechanism by enhancing + original named font creation method. + + Release tk4.2jp, November 24, 1996 + + (new release) Modified for the Tk4.2. + + (new release) Modified for the Tk4.1p1. + + (feature change) Eliminated exported global variables (they don't work with + Windows DLLs). The arrays of Kanji Encode/Decode functions (Tcl_KanjiEncode + and Tcl_KanjiDecode) are replaced with C functions (Tcl_KanjiEncode() and + Tcl_KanjiDecode()). + + (bug fix) Bug fixes for Windows version (by Mr. Hiroaki NAKAMURA). + + Release tk4.1jp_alpha, April 25, 1996 + + (new release) Modified for the Tk4.1. + + (new feature) A set of patches for Windows is contributed from + Mr. Hiroaki NAKAMURA. + + (new release) Modified for the Tk4.1b3. + + (new release) Modified for the Tk4.1b1. + + (new release) Modified for the Tk4.1a2. + + Release tk4.0p3jp, December 11, 1995 + + (bug fix) Fixed a bug in 'library/prolog.ps'. Now you can generate a + PostScript including kanji characters. + + (bug fix) Fixed a bug in tag priority of Text Widgets. If you specify + a kanji font with a tag, and then specify a ascii font with another tag, + kanji strings are displayed with the default kanji font. + + Release tk4.0jp, September 25, 1995 + + (bug fix) Fixed a bug in TkTextCharLayoutProc. 'ciPtr' was accidentally + allocated twice. + + (bug fix) Fixed a bug in ConfigureScale. 'gcValues.foreground' was + accidentally unitialized for 'scalePtr->troughGC'. + + (new features) For window managers that can handle compound text, wm command + now convert a string from STRING to COMPOUND_TEXT if the string contains + kanji characters. Mr. Motonori Hirano (m-hirano@sra.co.jp) contributed this + patch. + + (bug fix) Fixed a bug in the insert option of text widgets. Even if you + specify a tag for some attributes of text, sometimes it doesn't affect on + its appearence. + + (bug fix) Fixed a bug in tkWStr.c Use memset insted of bzero. + + (bug fix) Fixed a bug in tkMenu.c. Mismatched #endif remains a trace on a + variable which does not exist. + + Release tk4.0jp-beta, August 1, 1995 + + (bug fix) Fixed bug in TkWSTextExtents. The initial value of lbearing should + not be 0. + + (new release) Modified some test suites which generate errors according to + the kanji font. + + Release tk4.0jp-alpha, July 12, 1995 + + (new release) Lots of modifications according to the new release. + + Release tk3.6jp-update3, May 24, 1995 + + (bug fix) Handling of -font/-kanjifont options for text tags were incorrect. + the results of Tk_GetFontStruct() cannot be simply copied, + because of the reference counting. + + (bug fix) Tk_GetFontStruct takes Tk_Uid, not just "char *" for the fontname. + This bug causes an unnecessary XLoadQueryFont every time kanjiInput start/ + attribute command is invoked. + + (bug fix) Fixed bug in EntryFetchSelection to free memory properly. + + (bug fix) Fixed a bug in library/kinput.tcl. If font name contains blank + characters, over-the-spot type input causes some warning messages. + + (bug fix) When the kana-kanji converion is taking place, tk doesn't restore + the window field of forwarded key events, causing bind command to be confused. + + Release tk3.6jp-update2, August 25, 1994 + + (bug fix) The declaration of checkProtocol() has been taken out of a + function block. + + Release tk3.6jp-update1, February 14, 1994 + + (bug fix) Fixed bug in tkKinput2.c for systems (some 64bit CPUs including + DEC/Alpha) where 'sizeof(long)' > 4. + + (bug fix) Fixed 'xypos' widget command in tkTextDisp.c to handle folded + long lines correctly. + + (bug fix) TK_CONFIG_END had a different definition from the original. + This might cause some troubles when the user mixes the Japanization and + other extensions. + + (bug fix) Moved 'tkWStr.h' out of 'tk.h' since 'tk.h' is installed to the + system directory but 'tkWStr.h' is not. + + (bug fix) Eliminated every 'bstring' functions. + + Release tk3.6jp, December 7, 1993 + + (bug fix) Canvases couldn't generate correct PS outputs when the kanji font + doesn't have XLFD name. + + (bug fix) The caching of kanji fonts was incorrect. + + (new feature) Modified tkFont.c and tkWStr.c to handle ISO Latin1 encodings. + + (new feature) Modified tkKinput2.c to forward the key event on the widget to + the input server (i.e. kinput2). Thus the user doesn't have to move the + mouse cursor to the window of the input server. + + (bug fix) When several widgets require kanji input at a time, the input + server sent the conversion result to the wrong widget. + + (configuration change) Eliminated 'ctype-fix.h': this file was introduced + to fix the bug in the original Tcl/Tk. Since the bug fix is incorporated + into the original source code, this local bug fix is no longer needed. + + (bug fix) Fixed bug in tkKinput2.c to initialize the number of specified + attributes. + + (bug fix) Clone interpreter needs current position to be set before + executing 'cshow'. + + Release tk3.2jp-update1, August 26, 1993 + + Release tk3.2jp, July 9, 1993 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tk.h ./generic/tk.h *** ../../tk8.0.5/generic/tk.h Fri Feb 5 06:03:27 1999 --- ./generic/tk.h Fri Mar 12 00:36:35 1999 *************** *** 92,97 **** --- 92,100 ---- */ #ifdef XNQueryInputStyle + #ifdef XIM_IMPROVE + #include + #endif /* XIM_IMPROVE */ #define TK_USE_INPUT_METHODS #endif *************** *** 240,245 **** --- 243,251 ---- #define TK_CONFIG_WINDOW 20 #define TK_CONFIG_CUSTOM 21 #define TK_CONFIG_END 22 + #ifdef KANJI + #define TK_CONFIG_WSTRING 23 + #endif /* KANJI */ /* * Macro to use to fill in "offset" fields of Tk_ConfigInfos. *************** *** 503,508 **** --- 509,520 ---- (((Tk_FakeWin *) (tkwin))->internalBorderWidth) #define Tk_Parent(tkwin) (((Tk_FakeWin *) (tkwin))->parentPtr) #define Tk_Colormap(tkwin) (((Tk_FakeWin *) (tkwin))->atts.colormap) + #ifdef KANJI + /* + * Cheat macro for getting an Atom from dispPtr. + */ + #define Tk_UsefulAtom(tkwin, varName) (Atom)(((TkWindow *)(tkwin))->dispPtr->varName) + #endif /* KANJI */ /* * The structure below is needed by the macros above so that they can *************** *** 551,556 **** --- 563,573 ---- char *dummy17; ClientData dummy18; char *dummy19; + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + char *icDum0; + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ } Tk_FakeWin; /* *************** *** 829,834 **** --- 846,854 ---- int cursorOn; /* Non-zero means that an insertion cursor * should be displayed in focusItemPtr. * Read-only to items.*/ + #ifdef KANJI + int use_ctext; /* If true, use Compound Text for selection. */ + #endif /* KANJI */ } Tk_CanvasTextInfo; /* *************** *** 1459,1464 **** --- 1479,1622 ---- EXTERN void Tk_UpdatePointer _ANSI_ARGS_((Tk_Window tkwin, int x, int y, int state)); + #ifdef KANJI + + /* + * Definition for compound font. + */ + + #define TK_FONT_GENERIC 0 + #define TK_FONT_2BYTES 1 + #define TK_FONT_OTHER 2 + #define TK_FONT_COMPOUND 3 + + /* + * Exported procedure in tkFont.c + */ + EXTERN int Tk_GetFontType _ANSI_ARGS_((Tk_Font tkfont)); + EXTERN int Tk_GetCompoundDescendant _ANSI_ARGS_((Tk_Font tkfont, + Tk_Font *ascii, Tk_Font *kanji)); + + typedef struct Tk_WTextLayout_ *Tk_WTextLayout; + + /* + * Exported podcedure in platform depend Tk{Platform}Font.c + */ + + EXTERN int Tk_MeasureWChars _ANSI_ARGS_((Tk_Font tkfont, + CONST wchar *source, int maxChars, int maxPixels, + int flags, int *lengthPtr)); + EXTERN void Tk_DrawWChars _ANSI_ARGS_((Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + CONST wchar *source, int numChars, int x, + int y)); + /* + * Exported procedure in TkWFont.c + */ + + EXTERN int Tk_WTextWidth _ANSI_ARGS_((Tk_Font font, + CONST wchar *string, int numChars)); + EXTERN void Tk_UnderlineWChars _ANSI_ARGS_((Display *display, + Drawable drawable, GC gc, Tk_Font tkfont, + CONST wchar *source, int x, int y, int firstChar, + int lastChar)); + EXTERN Tk_WTextLayout Tk_ComputeWTextLayout _ANSI_ARGS_((Tk_Font font, + CONST wchar *string, int numChars, int wrapLength, + Tk_Justify justify, int flags, int *widthPtr, + int *heightPtr)); + EXTERN void Tk_FreeWTextLayout _ANSI_ARGS_(( + Tk_WTextLayout textLayout)); + EXTERN void Tk_DrawWTextLayout _ANSI_ARGS_((Display *display, + Drawable drawable, GC gc, Tk_WTextLayout layout, + int x, int y, int firstChar, int lastChar)); + EXTERN void Tk_UnderlineWTextLayout _ANSI_ARGS_(( + Display *display, Drawable drawable, GC gc, + Tk_WTextLayout layout, int x, int y, + int underline)); + EXTERN int Tk_PointToWChar _ANSI_ARGS_((Tk_WTextLayout layout, + int x, int y)); + EXTERN int Tk_WCharBbox _ANSI_ARGS_((Tk_WTextLayout layout, + int index, int *xPtr, int *yPtr, int *widthPtr, + int *heightPtr)); + EXTERN int Tk_DistanceToWTextLayout _ANSI_ARGS_(( + Tk_WTextLayout layout, int x, int y)); + EXTERN int Tk_IntersectWTextLayout _ANSI_ARGS_(( + Tk_WTextLayout layout, int x, int y, int width, + int height)); + EXTERN void Tk_WTextLayoutToPostscript _ANSI_ARGS_(( + Tcl_Interp *interp, Tk_WTextLayout layout)); + + /* + * Exported procedure in tkCmd.c + */ + + EXTERN int Tk_KanjiInputCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int argc, char **argv)); + + /* + * Exported procedure in tkKinsoku.c + */ + + EXTERN int Tk_KinsokuObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); + + /* + * Exported procedure in tkCtext.c + */ + + EXTERN char * Tk_WStrToString _ANSI_ARGS_((wchar *ws, int n)); + EXTERN char * Tk_WStrToCtext _ANSI_ARGS_((wchar *ws, int n)); + EXTERN wchar * Tk_CtextToWStr _ANSI_ARGS_((char *ct, int n)); + + #ifdef KINPUT2 + + /* + * Exported procedure in ../unix/TkKinput2.c + */ + + EXTERN int Tk_Kinput2Start _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, int argc, char **argv)); + EXTERN int Tk_Kinput2End _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin)); + EXTERN int Tk_Kinput2Attribute _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, int argc, char **argv)); + EXTERN int Tk_Kinput2AttributeInfo _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, char *attrName)); + + + #endif /* KINPUT2 */ + + #ifdef TK_KANJI_OK + + #ifndef TK_REPLACE_TO_KANJIFUNC + #define TK_REPLACE_TO_KANJIFUNC + /* + * Replace below procedure and structure/type to wide string version. + */ + #define LayoutChunk WLayoutChunk + #define TextLayout WTextLayout + #define Tk_TextLayout Tk_WTextLayout + + #define Tk_TextWidth Tk_WTextWidth + #define Tk_DrawChars Tk_DrawWChars + #define Tk_MeasureChars Tk_MeasureWChars + #define Tk_UnderlineChars Tk_UnderlineWChars + #define Tk_ComputeTextLayout Tk_ComputeWTextLayout + #define Tk_FreeTextLayout Tk_FreeWTextLayout + #define Tk_DrawTextLayout Tk_DrawWTextLayout + #define Tk_UnderlineTextLayout Tk_UnderlineWTextLayout + #define Tk_PointToChar Tk_PointToWChar + #define Tk_CharBbox Tk_WCharBbox + #define Tk_DistanceToTextLayout Tk_DistanceToWTextLayout + #define Tk_IntersectTextLayout Tk_IntersectWTextLayout + #define Tk_TextLayoutToPostscript Tk_WTextLayoutToPostscript + + #endif /* TK_REPLACE_TO_KANJIFUNC */ + + #endif /* TK_KANJI_OK */ + + #endif /* KANJI */ + /* * Tcl commands exported by Tk: */ *************** *** 1501,1506 **** --- 1659,1670 ---- Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_GridCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + EXTERN int Tk_ImconfigureObjCmd _ANSI_ARGS_((ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ EXTERN int Tk_ImageCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); EXTERN int Tk_LabelCmd _ANSI_ARGS_((ClientData clientData, diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkBind.c ./generic/tkBind.c *** ../../tk8.0.5/generic/tkBind.c Sat Oct 10 09:30:36 1998 --- ./generic/tkBind.c Fri Mar 12 00:36:37 1999 *************** *** 74,80 **** --- 74,87 ---- * */ + #ifdef KANJI + /* + * Increase event buffer for rapid invocation of kinput2. + */ + #define EVENT_BUFFER_SIZE 120 + #else #define EVENT_BUFFER_SIZE 30 + #endif /* KANJI */ typedef struct BindingTable { XEvent eventRing[EVENT_BUFFER_SIZE];/* Circular queue of recent events * (higher indices are for more recent *************** *** 1435,1440 **** --- 1442,1451 ---- dispPtr = ((TkWindow *) tkwin)->dispPtr; bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo; + #ifdef KANJI + memset((VOID *)&detail, 0, sizeof(Detail)); + #endif + /* * Add the new event to the ring of saved events for the * binding table. Two tricky points: *************** *** 1640,1645 **** --- 1651,1659 ---- */ Tcl_DStringAppend(&scripts, "", 1); + #ifdef XIM_DEBUG + fprintf(stderr, "debugEv: proc '%s'\n", Tcl_DStringValue(&scripts)); + #endif /* XIM_DEBUG */ } } if (Tcl_DStringLength(&scripts) == 0) { *************** *** 2209,2218 **** --- 2223,2254 ---- int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl * list element. */ int number, flags, length; + #ifdef TK_USE_INPUT_METHODS + #ifdef USE_FIXED_XMBLOOKUPSTR + #define NUM_SIZE 40 + #else + /* + * Increase buffersize. + */ + #define NUM_SIZE 1024 + #endif /* USE_FIXWD_XMBLOOKUPSTR */ + #else #define NUM_SIZE 40 + #endif /* TK_USE_INPUT_METHODS */ char *string; char numStorage[NUM_SIZE+1]; + #ifdef USE_FIXED_XMBLOOKUPSTR + #ifdef TK_USE_INPUT_METHODS + /* Must not free! */ + static char *overFlows = NULL; + static int overFlowLen = NUM_SIZE + 1; + + if (overFlows == NULL) { + overFlows = (char *)ckalloc(sizeof(char) * (NUM_SIZE + 1)); + } + #endif /* TK_USE_INPUT_METHODS */ + #endif /* USE_FIXED_XMBLOOKUPSTR */ if (eventPtr->type < TK_LASTEVENT) { flags = flagArray[eventPtr->type]; } else { *************** *** 2373,2378 **** --- 2409,2435 ---- Status status; if ((winPtr->inputContext != NULL) && (eventPtr->type == KeyPress)) { + #ifdef USE_FIXED_XMBLOOKUPSTR + numChars = XmbLookupString(winPtr->inputContext, + &eventPtr->xkey, overFlows, overFlowLen, + (KeySym *) NULL, &status); + if (status == XBufferOverflow && numChars > 0) { + if (numChars > overFlowLen) { + overFlowLen = numChars; + overFlows = (char *)ckrealloc(overFlows, sizeof(char) * (numChars + 1)); + } + numChars = XmbLookupString(winPtr->inputContext, + &eventPtr->xkey, overFlows, numChars, + (KeySym *) NULL, &status); + } + if ((status != XLookupChars) && + (status != XLookupBoth)) { + numChars = 0; + } + overFlows[numChars] = '\0'; + string = overFlows; + goto doString; + #endif /* USE_FIXED_XMBLOOKUPSTR */ numChars = XmbLookupString(winPtr->inputContext, &eventPtr->xkey, numStorage, NUM_SIZE, (KeySym *) NULL, &status); *************** *** 2380,2386 **** && (status != XLookupBoth)) { numChars = 0; } ! } else { numChars = XLookupString(&eventPtr->xkey, numStorage, NUM_SIZE, (KeySym *) NULL, (XComposeStatus *) NULL); --- 2437,2443 ---- && (status != XLookupBoth)) { numChars = 0; } ! } else { numChars = XLookupString(&eventPtr->xkey, numStorage, NUM_SIZE, (KeySym *) NULL, (XComposeStatus *) NULL); diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkButton.c ./generic/tkButton.c *** ../../tk8.0.5/generic/tkButton.c Tue Sep 15 03:23:04 1998 --- ./generic/tkButton.c Fri Mar 12 00:36:38 1999 *************** *** 162,169 **** --- 162,174 ---- {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocus), BUTTON_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_NULL_OK}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-text", "text", "Text", + DEF_BUTTON_TEXT, Tk_Offset(TkButton, text), ALL_MASK}, + #else {TK_CONFIG_STRING, "-text", "text", "Text", DEF_BUTTON_TEXT, Tk_Offset(TkButton, text), ALL_MASK}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_STRING, "-textvariable", "textVariable", "Variable", DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarName), ALL_MASK|TK_CONFIG_NULL_OK}, *************** *** 824,829 **** --- 829,849 ---- char *value; value = Tcl_GetVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY); + #ifdef TK_KANJI_OK + if (value == NULL) { + if (Tcl_SetVar(interp, butPtr->textVarName, + Tcl_DecodeWStr(interp, butPtr->text, NULL), + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { + return TCL_ERROR; + } + } else { + wchar *old = butPtr->text; + butPtr->text = Tcl_GetWStr(NULL, value, NULL); + if (old != NULL) { + Tcl_FreeWStr(old); + } + } + #else if (value == NULL) { if (Tcl_SetVar(interp, butPtr->textVarName, butPtr->text, TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) { *************** *** 836,841 **** --- 856,862 ---- butPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(butPtr->text, value); } + #endif /* TK_KANJI_OK */ Tcl_TraceVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, (ClientData) butPtr); *************** *** 1231,1236 **** --- 1252,1260 ---- { register TkButton *butPtr = (TkButton *) clientData; char *value; + #ifdef TK_KANJI_OK + wchar *old = butPtr->text; + #endif /* TK_KANJI_OK */ /* * If the variable is unset, then immediately recreate it unless *************** *** 1239,1246 **** --- 1263,1277 ---- if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { + + #ifdef TK_KANJI_OK + Tcl_SetVar(interp, butPtr->textVarName, + Tcl_DecodeWStr(interp, butPtr->text, NULL), + TCL_GLOBAL_ONLY); + #else Tcl_SetVar(interp, butPtr->textVarName, butPtr->text, TCL_GLOBAL_ONLY); + #endif /* TK_KANJI_OK */ Tcl_TraceVar(interp, butPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ButtonTextVarProc, clientData); *************** *** 1252,1262 **** --- 1283,1300 ---- if (value == NULL) { value = ""; } + #ifdef TK_KANJI_OK + butPtr->text = Tcl_GetWStr(NULL, value, NULL); + if (old != NULL) { + Tcl_FreeWStr(old); + } + #else if (butPtr->text != NULL) { ckfree(butPtr->text); } butPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(butPtr->text, value); + #endif /* TK_KANJI_OK */ TkpComputeButtonGeometry(butPtr); if ((butPtr->tkwin != NULL) && Tk_IsMapped(butPtr->tkwin) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkButton.h ./generic/tkButton.h *** ../../tk8.0.5/generic/tkButton.h Tue Sep 15 03:23:04 1998 --- ./generic/tkButton.h Fri Mar 12 00:36:39 1999 *************** *** 15,20 **** --- 15,24 ---- #ifndef _TKBUTTON #define _TKBUTTON + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #ifndef _TKINT #include "tkInt.h" #endif *************** *** 43,51 **** /* * Information about what's in the button. */ ! char *text; /* Text to display in button (malloc'ed) * or NULL. */ int underline; /* Index of character to underline. < 0 means * don't underline anything. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. --- 47,59 ---- /* * Information about what's in the button. */ ! #ifdef TK_KANJI_OK ! wchar *text; /* Text to display in button (malloc'ed) ! * or NULL. */ ! #else char *text; /* Text to display in button (malloc'ed) * or NULL. */ + #endif /* TK_KANJI_OK */ int underline; /* Index of character to underline. < 0 means * don't underline anything. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkCanvPs.c ./generic/tkCanvPs.c *** ../../tk8.0.5/generic/tkCanvPs.c Wed Sep 23 03:57:16 1998 --- ./generic/tkCanvPs.c Fri Mar 12 00:36:41 1999 *************** *** 11,23 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkCanvPs.c,v 1.4 1998/09/22 18:57:16 stanton Exp $ */ #include "tkInt.h" #include "tkCanvas.h" #include "tkPort.h" /* * See tkCanvas.h for key data structures used to implement canvases. */ --- 11,31 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkCanvPs.c,v 1.16 1999/03/11 15:36:41 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #include "tkInt.h" #include "tkCanvas.h" #include "tkPort.h" + #ifdef TK_KANJI_OK + #include "tkFont.h" + #endif /* TK_KANJI_OK */ + /* * See tkCanvas.h for key data structures used to implement canvases. */ *************** *** 359,364 **** --- 367,556 ---- dup lineLength gt {/lineLength exch def}", /* End of part 4 */ + #ifdef TK_KANJI_OK + /* Start of part 5 (1546 characters) */ + " {pop} ifelse\n\ + newpath\n\ + } forall\n\ + \n\ + % Compute the baseline offset and the actual font height.\n\ + \n\ + 0 0 moveto (TXygqPZ) false charpath\n\ + pathbbox dup /baseline exch def\n\ + exch pop exch sub /height exch def pop\n\ + newpath\n\ + \n\ + % Translate coordinates first so that the origin is at the upper-left\n\ + % corner of the text's bounding box. Remember that x and y for\n\ + % positioning are still on the stack.\n\ + \n\ + translate\n\ + lineLength xoffset mul\n\ + strings length 1 sub spacing mul height add yoffset mul translate\n\ + \n\ + % Now use the baseline and justification information to translate so\n\ + % that the origin is at the baseline and positioning point for the\n\ + % first line of text.\n\ + \n\ + justify lineLength mul baseline neg translate\n\ + \n\ + % Iterate over each of the lines to output it. For each line,\n\ + % compute its width again so it can be properly justified, then\n\ + % display it.\n\ + \n\ + strings {\n\ + dup stringwidth pop\n\ + justify neg mul 0 moveto\n\ + stipple {\n\ + \n\ + % The text is stippled, so turn it into a path and print\n\ + % by calling StippledText, which in turn calls StippleFill.\n\ + % Unfortunately, many Postscript interpreters will get\n\ + % overflow errors if we try to do the whole string at\n\ + % once, so do it a character at a time.\n\ + \n\ + gsave\n\ + /char (X) def\n\ + {\n\ + char 0 3 -1 roll put\n\ + currentpoint\n\ + gsave\n\ + char true charpath clip StippleText\n\ + grestore\n\ + char stringwidth translate\n\ + moveto\n\ + } forall\n\ + grestore\n\ + } {show} ifelse\n\ + 0 spacing neg translate\n\ + } forall\n\ + } bind def\n\ + \n\ + ", + /* Start of part 6 */ + "% Japanization stuff.\n\ + \n\ + % This eucfont came from fixeucfont-1.2 by Mr. Norio Katayama\n\ + % (katayama@rd.nacsis.ac.jp). Thank you :)\n\ + % Modified: Feb 10 1999 for hankaku kana support.\n\ + % Special thanks to Mr. Toyohisa Kameyama (kameyama@sra.co.jp).\n\ + \n\ + /CIDeucfont {\n\ + /KanaFont exch dup type /nametype eq { findfont } if def\n\ + userdict /fixeucfont_dict known not {\n\ + userdict begin\n\ + /fixeucfont_dict 2 dict begin\n\ + /UpperByteEncoding [\n\ + 16#00 1 16#0D { pop 0 } for\n\ + 78 % 0x0e SS2 kanaFont map. adding to last of basefont vector.\n\ + 16#0f 1 16#20 { pop 0 } for\n\ + 16#21 1 16#28 { 16#20 sub } for\n\ + 16#29 1 16#2F { pop 0 } for\n\ + 16#30 1 16#74 { 16#27 sub } for\n\ + 16#75 1 16#FF { pop 0 } for\n\ + ] def\n\ + /LowerByteEncoding [\n\ + 16#00 1 16#A0 { pop /.notdef } for\n\ + 16#A1 1 16#FE { 16#80 sub 16 2 string cvrs\n\ + (cXX) dup 1 4 -1 roll\n\ + putinterval cvn } for\n\ + /.notdef\n\ + ] def\n\ + currentdict\n\ + end def\n\ + end\n\ + } if\n\ + 12 dict begin\n\ + dup type /nametype eq { findfont } if\n\ + dup /WMode known {\n\ + dup /WMode get /WMode exch def\n\ + WMode 1 eq {\n\ + [0.0 1.0 -1.0 0.0 0.0 0.30] makefont\n\ + } if\n\ + } if\n\ + %\n\ + % 7+8 bit EUC font\n\ + %\n\ + 12 dict begin\n\ + /EUCFont exch def\n\ + /FontInfo (7+8 bit EUC font) readonly def\n\ + /PaintType 0 def\n\ + /FontType 0 def\n\ + /FontMatrix matrix def\n\ + % /FontName\n\ + /Encoding fixeucfont_dict /UpperByteEncoding get def\n\ + /FMapType 2 def\n\ + EUCFont /WMode known\n\ + { EUCFont /WMode get /WMode exch def }\n\ + { /WMode 0 def } ifelse\n\ + /FDepVector [\n\ + EUCFont /FDepVector get 0 get\n\ + [ 16#21 1 16#28 {} for 16#30 1 16#74 {} for ]\n\ + {\n\ + 13 dict begin\n\ + /EUCFont EUCFont def\n\ + /UpperByte exch 16#80 add def \n\ + % /FontName\n\ + /FontInfo (EUC lower byte font) readonly def\n\ + /PaintType 0 def\n\ + /FontType 3 def\n\ + /FontMatrix matrix def\n\ + /FontBBox {0 0 0 0} def\n\ + /Encoding fixeucfont_dict /LowerByteEncoding get def\n\ + % /UniqueID\n\ + % /WMode\n\ + ", + /* End of part 6 */ + /* Start of part 7 */ + + " /BuildChar {\n\ + gsave\n\ + exch dup /EUCFont get setfont\n\ + /UpperByte get\n\ + 2 string\n\ + dup 0 4 -1 roll put\n\ + dup 1 4 -1 roll put\n\ + dup stringwidth setcharwidth\n\ + 0 0 moveto show\n\ + grestore\n\ + } bind def\n\ + currentdict\n\ + end\n\ + /lowerbytefont exch definefont\n\ + } forall\n\ + KanaFont\n\ + ] def\n\ + currentdict\n\ + end\n\ + /kanjifont exch definefont\n\ + exch\n\ + \n\ + dup type /nametype eq { findfont } if\n\ + exch\n\ + \n\ + /FDepVector [ 4 2 roll ] def\n\ + /FontType 0 def\n\ + /FMapType 4 def\n\ + /FontMatrix matrix def\n\ + /Encoding [ 0 1 ] def\n\ + /FontBBox {0 0 0 0} def\n\ + dup /FontName exch def\n\ + currentdict\n\ + end\n\ + definefont pop\n\ + } def\n\ + \n\ + /eucfont {\n\ + 3 index FontDirectory exch known not {\n\ + CIDeucfont\n\ + } { pop pop pop pop } ifelse\n\ + } def\n\ + \n\ + %%EndProlog\n\ + \n\ + ", + /* End of part 7 */ + #else /* Start of part 5 (1546 characters) */ " {pop} ifelse\n\ newpath\n\ *************** *** 420,426 **** %%EndProlog\n\ ", /* End of part 5 */ ! NULL /* End of data marker */ }; --- 612,618 ---- %%EndProlog\n\ ", /* End of part 5 */ ! #endif /* TK_KANJI_OK */ NULL /* End of data marker */ }; *************** *** 984,989 **** --- 1176,1262 ---- Tcl_AppendResult(interp, string, (char *) NULL); return TCL_OK; } + #ifdef TK_KANJI_OK + + static char * + GenCompositeFont(interp, compName, kanaName, asciiName, kanjiName) + Tcl_Interp *interp; + char *compName; + char *kanaName; + char *asciiName; + char *kanjiName; + { + int i; + int n = strlen(compName); + int kanjiCode = TCL_ANY; + char *validName = NULL; + int needFree = 0; + char *ret = NULL; + + if (Tcl_KanjiString(interp, compName, compName + n, &kanjiCode) == TCL_NOT_KANJI) { + validName = compName; + } else { + char *buf; + unsigned char c; + int used = 0; + wchar *wstr; + int wLen; + char *newStr; + int newLen; + + needFree = 1; + wLen = Tcl_KanjiEncode(kanjiCode, compName, NULL); + wstr = (wchar *)ckalloc((wLen + 1) * sizeof(wchar)); + (void)Tcl_KanjiEncode(kanjiCode, compName, wstr); + newLen = Tcl_KanjiDecode(TCL_EUC, wstr, NULL); + newStr = (char *)ckalloc((newLen + 1) * sizeof(char)); + (void)Tcl_KanjiDecode(TCL_EUC, wstr, newStr); + ckfree((char *)wstr); + + buf = (char *)ckalloc((newLen * 4 + 1) * sizeof(char)); + + /* + * Generate valid name for composite font. + */ + for (i = 0; i < newLen; i++) { + c = newStr[i]; + if (c == '(' || c == ')' || c == '\\' || c < 0x20 || c >= 0x80) { + sprintf(buf + used, "\\%03o", c); + used += 4; + } else { + buf[used++] = c; + } + } + buf[used] = 0; + validName = buf; + } + + Tcl_AppendResult(interp, "(", validName, ") cvn", + " /", asciiName, + " /", kanjiName, + " /", kanaName, + " eucfont\n", NULL); + + ret = Tk_GetUid(validName); + if (needFree == 1) { + ckfree(validName); + } + + return ret; + } + + + static char * + GetKanaFontName(kanjiName) + char *kanjiName; + { + if (strcmp(kanjiName, "Ryumin-Light-EUC-H") == 0) { + return "Ryumin-Light.Hankaku"; + } else { + return "GothicBBB-Medium.Hankaku"; + } + } + #endif /* TK_KANJI_OK */ /* *-------------------------------------------------------------- *************** *** 1022,1027 **** --- 1295,1314 ---- char pointString[20]; Tcl_DString ds; int i, points; + #ifdef TK_KANJI_OK + Tk_Font ascii = NULL; + Tk_Font kanji = NULL; + Tk_Window tkwin = Tk_MainWindow(interp); + int fontType = Tk_FontType(tkfont); + Tk_Uid asciiName = NULL; + Tk_Uid kanjiName = NULL; + Tk_Uid kanaName = NULL; + char *compName = NULL; + char **psFontNames; + int numFonts; + int asciiPoints; + int kanjiPoints; + #endif /* TK_KANJI_OK */ /* * First, look up the font's name in the font map, if there is one. *************** *** 1054,1079 **** if ((size <= 0) || (*end != 0)) { goto badMapEntry; } ! Tcl_DStringAppend(&ds, argv[0], -1); points = (int) size; ckfree((char *) argv); goto findfont; } ! } points = Tk_PostscriptFontName(tkfont, &ds); findfont: sprintf(pointString, "%d", points); Tcl_AppendResult(interp, "/", Tcl_DStringValue(&ds), " findfont ", pointString, " scalefont ", (char *) NULL); if (strncasecmp(Tcl_DStringValue(&ds), "Symbol", 7) != 0) { Tcl_AppendResult(interp, "ISOEncode ", (char *) NULL); } Tcl_AppendResult(interp, "setfont\n", (char *) NULL); Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); Tcl_DStringFree(&ds); return TCL_OK; --- 1341,1486 ---- if ((size <= 0) || (*end != 0)) { goto badMapEntry; } ! #ifdef TK_KANJI_OK ! if (Tcl_SplitList(interp, argv[0], &numFonts, &psFontNames) != TCL_OK) { ! goto badMapEntry; ! } ! if (numFonts < 1) { ! ckfree((char *)psFontNames); ! goto badMapEntry; ! } ! switch (numFonts) { ! case 2: { ! asciiName = Tk_GetUid(psFontNames[0]); ! kanjiName = Tk_GetUid(psFontNames[1]); ! kanaName = Tk_GetUid(GetKanaFontName(kanjiName)); ! compName = GenCompositeFont(interp, name, kanaName, asciiName, kanjiName); ! Tcl_DStringAppend(&ds, compName, -1); ! ckfree((char *)psFontNames); ! break; ! } ! case 1: { ! switch (fontType) { ! case TK_FONT_GENERIC: { ! asciiName = Tk_GetUid(psFontNames[0]); ! kanjiName = Tk_GetUid("Ryumin-Light-EUC-H"); ! break; ! } ! case TK_FONT_2BYTES: { ! asciiName = Tk_GetUid("Courier"); ! kanjiName = Tk_GetUid(psFontNames[0]); ! break; ! } ! default: { ! ckfree((char *)psFontNames); ! goto badMapEntry; ! break; ! } ! } ! kanaName = Tk_GetUid(GetKanaFontName(kanjiName)); ! compName = GenCompositeFont(interp, name, kanaName, asciiName, kanjiName); ! Tcl_DStringAppend(&ds, compName, -1); ! ckfree((char *)psFontNames); ! break; ! } ! default: { ! ckfree((char *)psFontNames); ! goto badMapEntry; ! break; ! } ! } ! #else Tcl_DStringAppend(&ds, argv[0], -1); + #endif /* TK_KANJI_OK */ points = (int) size; ckfree((char *) argv); goto findfont; } ! } ! ! #ifdef TK_KANJI_OK ! TkpGetFailsafeFont(tkfont, &ascii, &kanji); ! points = Tk_FontSize(tkfont); ! if (points < 0) { ! points = TkpConvertPixelToPoint(tkwin, -points); ! } ! asciiPoints = kanjiPoints = points; ! if (ascii != NULL) { ! asciiPoints = Tk_PostscriptFontName(ascii, &ds); ! if (asciiPoints < 0) { ! asciiPoints = TkpConvertPixelToPoint(tkwin, -asciiPoints); ! } ! #ifdef __WIN32__ ! if (Tk_FontType(ascii) == TK_FONT_2BYTES) { ! if (strcmp(Tcl_DStringValue(&ds), "GothicBBB-Medium-EUC-H") == 0) ! asciiName = Tk_GetUid("GothicBBB-Medium.Roman"); ! else ! asciiName = Tk_GetUid("Ryumin-Light.Roman"); ! } else ! #endif /* __WIN32__ */ ! asciiName = Tk_GetUid(Tcl_DStringValue(&ds)); ! Tcl_DStringFree(&ds); ! } else { ! asciiName = Tk_GetUid("Courier"); ! } + if (kanji != NULL) { + kanjiPoints = Tk_PostscriptFontName(kanji, &ds); + if (kanjiPoints < 0) { + kanjiPoints = TkpConvertPixelToPoint(tkwin, -kanjiPoints); + } + kanjiName = Tk_GetUid(Tcl_DStringValue(&ds)); + Tcl_DStringFree(&ds); + } else { + kanjiName = Tk_GetUid("Ryumin-Light-EUC-H"); + } + + switch (fontType) { + case TK_FONT_GENERIC: { + points = asciiPoints; + break; + } + case TK_FONT_2BYTES: { + points = kanjiPoints; + break; + } + case TK_FONT_COMPOUND: { + points = (asciiPoints < kanjiPoints) ? asciiPoints : kanjiPoints; + break; + } + } + kanaName = Tk_GetUid(GetKanaFontName(kanjiName)); + compName = GenCompositeFont(interp, Tk_NameOfFont(tkfont), kanaName, asciiName, kanjiName); + Tcl_DStringAppend(&ds, compName, -1); + #else points = Tk_PostscriptFontName(tkfont, &ds); + #endif /* TK_KANJI_OK */ findfont: sprintf(pointString, "%d", points); + #ifdef TK_KANJI_OK + Tcl_AppendResult(interp, "(", Tcl_DStringValue(&ds), ") cvn findfont ", + pointString, " scalefont ", (char *) NULL); + #else Tcl_AppendResult(interp, "/", Tcl_DStringValue(&ds), " findfont ", pointString, " scalefont ", (char *) NULL); if (strncasecmp(Tcl_DStringValue(&ds), "Symbol", 7) != 0) { Tcl_AppendResult(interp, "ISOEncode ", (char *) NULL); } + #endif /* TK_KANJI_OK */ Tcl_AppendResult(interp, "setfont\n", (char *) NULL); + #ifdef TK_KANJI_OK + if (kanjiName != NULL && asciiName != NULL && kanaName != NULL) { + Tcl_CreateHashEntry(&psInfoPtr->fontTable, asciiName, &i); + Tcl_CreateHashEntry(&psInfoPtr->fontTable, kanjiName, &i); + Tcl_CreateHashEntry(&psInfoPtr->fontTable, kanaName, &i); + } else { + panic("kanji, kana, ascii font names must NOT be NULL."); + } + #else Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); + #endif /* TK_KANJI_OK */ Tcl_DStringFree(&ds); return TCL_OK; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkCanvText.c ./generic/tkCanvText.c *** ../../tk8.0.5/generic/tkCanvText.c Fri Oct 16 09:46:19 1998 --- ./generic/tkCanvText.c Fri Mar 12 00:36:42 1999 *************** *** 9,23 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkCanvText.c,v 1.3 1998/10/16 00:46:19 rjohnson Exp $ */ #include #include "tkInt.h" #include "tkCanvas.h" #include "tkPort.h" #include "default.h" /* * The structure below defines the record for each text item. */ --- 9,31 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkCanvText.c,v 1.7 1999/03/11 15:36:42 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #include #include "tkInt.h" #include "tkCanvas.h" #include "tkPort.h" #include "default.h" + #ifdef TK_KANJI_OK + #include "default.h" + #endif /* TK_KANJI_OK */ + /* * The structure below defines the record for each text item. */ *************** *** 48,54 **** --- 56,66 ---- Tk_Font tkfont; /* Font for drawing text. */ Tk_Justify justify; /* Justification mode for text. */ Pixmap stipple; /* Stipple bitmap for text, or None. */ + #ifdef TK_KANJI_OK + wchar *text; + #else char *text; /* Text for item (malloc-ed). */ + #endif /* TK_KANJI_OK */ int width; /* Width of lines for word-wrap, pixels. * Zero means no word-wrap. */ *************** *** 96,103 **** --- 108,120 ---- (char *) NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK}, {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL, (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-text", (char *) NULL, (char *) NULL, + "", Tk_Offset(TextItem, text), 0}, + #else {TK_CONFIG_STRING, "-text", (char *) NULL, (char *) NULL, "", Tk_Offset(TextItem, text), 0}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL, "0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT}, {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL, *************** *** 400,406 **** --- 417,428 ---- * to keep them inside the item. */ + + #ifdef TK_KANJI_OK + textPtr->numChars = Tcl_WStrlen(textPtr->text); + #else textPtr->numChars = strlen(textPtr->text); + #endif /* TK_KANJI_OK */ if (textInfoPtr->selItemPtr == itemPtr) { if (textInfoPtr->selectFirst >= textPtr->numChars) { textInfoPtr->selItemPtr = NULL; *************** *** 456,462 **** --- 478,488 ---- Tk_FreeBitmap(display, textPtr->stipple); } if (textPtr->text != NULL) { + #ifdef TK_KANJI_OK + Tcl_FreeWStr(textPtr->text); + #else ckfree(textPtr->text); + #endif /* TK_KANJI_OK */ } Tk_FreeTextLayout(textPtr->textLayout); *************** *** 763,772 **** --- 789,806 ---- { TextItem *textPtr = (TextItem *) itemPtr; int length; + #ifdef TK_KANJI_OK + wchar *new = Tcl_GetWStr(NULL, string, NULL); + #else char *new; + #endif /* TK_KANJI_OK */ Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; + #ifdef TK_KANJI_OK + length = Tcl_WStrlen(new); + #else length = strlen(string); + #endif /* TK_KANJI_OK */ if (length == 0) { return; } *************** *** 777,788 **** --- 811,828 ---- beforeThis = textPtr->numChars; } + #ifdef TK_KANJI_OK + textPtr->text = Tcl_InsertWStr(((TkCanvas *)canvas)->interp, + textPtr->text, beforeThis, new); + Tcl_FreeWStr(new); + #else new = (char *) ckalloc((unsigned) (textPtr->numChars + length + 1)); strncpy(new, textPtr->text, (size_t) beforeThis); strcpy(new+beforeThis, string); strcpy(new+beforeThis+length, textPtr->text+beforeThis); ckfree(textPtr->text); textPtr->text = new; + #endif /* TK_KANJI_OK */ textPtr->numChars += length; /* *************** *** 835,841 **** --- 875,883 ---- { TextItem *textPtr = (TextItem *) itemPtr; int count; + #ifndef TK_KANJI_OK char *new; + #endif /* !TK_KANJI_OK */ Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; if (first < 0) { *************** *** 849,859 **** --- 891,906 ---- } count = last + 1 - first; + #ifdef TK_KANJI_OK + textPtr->text = Tcl_DeleteWStr(((TkCanvas *)canvas)->interp, + textPtr->text, first, count); + #else new = (char *) ckalloc((unsigned) (textPtr->numChars + 1 - count)); strncpy(new, textPtr->text, (size_t) first); strcpy(new+first, textPtr->text+last+1); ckfree(textPtr->text); textPtr->text = new; + #endif /* TK_KANJI_OK */ textPtr->numChars -= count; /* *************** *** 1205,1222 **** --- 1252,1293 ---- int count; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; + #ifdef TK_KANJI_OK + char *str; + + count = textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst; + if (textInfoPtr->selectLast == textPtr->numChars) { + count -= 1; + } + if (textInfoPtr->use_ctext) { + str = Tk_WStrToCtext(textPtr->text + textInfoPtr->selectFirst, count); + } else { + str = Tk_WStrToString(textPtr->text + textInfoPtr->selectFirst, count); + } + if (str == NULL) return 0; + count = strlen(str) - offset; + #else count = textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst - offset; if (textInfoPtr->selectLast == textPtr->numChars) { count -= 1; } + #endif /* TK_KANJI_OK */ if (count > maxBytes) { count = maxBytes; } if (count <= 0) { + #ifdef TK_KANJI_OK + ckfree(str); + #endif /* TK_KANJI_OK */ return 0; } + #ifdef TK_KANJI_OK + strncpy(buffer, str + offset, (size_t) count); + ckfree(str); + #else strncpy(buffer, textPtr->text + textInfoPtr->selectFirst + offset, (size_t) count); + #endif /* TK_KANJI_OK */ buffer[count] = '\0'; return count; } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkCanvas.c ./generic/tkCanvas.c *** ../../tk8.0.5/generic/tkCanvas.c Wed Oct 14 03:13:06 1998 --- ./generic/tkCanvas.c Fri Mar 12 00:36:43 1999 *************** *** 12,20 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkCanvas.c,v 1.3 1998/10/13 18:13:06 rjohnson Exp $ */ #include "default.h" #include "tkInt.h" #include "tkPort.h" --- 12,24 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkCanvas.c,v 1.6 1999/03/11 15:36:43 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #include "default.h" #include "tkInt.h" #include "tkPort.h" *************** *** 181,186 **** --- 185,195 ---- static int CanvasFetchSelection _ANSI_ARGS_(( ClientData clientData, int offset, char *buffer, int maxBytes)); + #ifdef TK_KANJI_OK + static int CanvasFetchSelectionCtext _ANSI_ARGS_(( + ClientData clientData, int offset, + char *buffer, int maxBytes)); + #endif /* TK_KANJI_OK */ static Tk_Item * CanvasFindClosest _ANSI_ARGS_((TkCanvas *canvasPtr, double coords[2])); static void CanvasFocusProc _ANSI_ARGS_((TkCanvas *canvasPtr, *************** *** 368,373 **** --- 377,394 ---- CanvasBindProc, (ClientData) canvasPtr); Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING, CanvasFetchSelection, (ClientData) canvasPtr, XA_STRING); + #ifdef TK_KANJI_OK + Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(canvasPtr->tkwin, textAtom), + CanvasFetchSelectionCtext, + (ClientData) canvasPtr, + Tk_UsefulAtom(canvasPtr->tkwin, compoundTextAtom)); + Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(canvasPtr->tkwin, compoundTextAtom), + CanvasFetchSelectionCtext, + (ClientData) canvasPtr, + Tk_UsefulAtom(canvasPtr->tkwin, compoundTextAtom)); + #endif /* TK_KANJI_OK */ if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) { goto error; } *************** *** 3487,3496 **** --- 3508,3564 ---- if (canvasPtr->textInfo.selItemPtr->typePtr->selectionProc == NULL) { return -1; } + #ifdef TK_KANJI_OK + canvasPtr->textInfo.use_ctext = 0; + #endif /* TK_KANJI_OK */ + return (*canvasPtr->textInfo.selItemPtr->typePtr->selectionProc)( + (Tk_Canvas) canvasPtr, canvasPtr->textInfo.selItemPtr, offset, + buffer, maxBytes); + } + #ifdef KANJI + + /* + *-------------------------------------------------------------- + * + * CanvasFetchSelectionCtext -- + * + * This procedure is similar to CanvasFetchSelection + * except it use COMPOUND_TEXT encoding for the selection. + * + * Results: + * See CanvasFetchSelection. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static int + CanvasFetchSelectionCtext(clientData, offset, buffer, maxBytes) + ClientData clientData; /* Information about canvas widget. */ + int offset; /* Offset within selection of first + * character to be returned. */ + char *buffer; /* Location in which to place + * selection. */ + int maxBytes; /* Maximum number of bytes to place + * at buffer, not including terminating + * NULL character. */ + { + TkCanvas *canvasPtr = (TkCanvas *) clientData; + + if (canvasPtr->textInfo.selItemPtr == NULL) { + return -1; + } + if (canvasPtr->textInfo.selItemPtr->typePtr->selectionProc == NULL) { + return -1; + } + canvasPtr->textInfo.use_ctext = 1; return (*canvasPtr->textInfo.selItemPtr->typePtr->selectionProc)( (Tk_Canvas) canvasPtr, canvasPtr->textInfo.selItemPtr, offset, buffer, maxBytes); } + #endif /* KANJI */ /* *---------------------------------------------------------------------- diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkClipboard.c ./generic/tkClipboard.c *** ../../tk8.0.5/generic/tkClipboard.c Tue Sep 15 03:23:07 1998 --- ./generic/tkClipboard.c Fri Mar 12 00:36:44 1999 *************** *** 444,452 **** --- 444,465 ---- c = argv[1][0]; length = strlen(argv[1]); if ((c == 'a') && (strncmp(argv[1], "append", length) == 0)) { + #ifdef KANJI + Atom format; + #else Atom target, format; + #endif /* KANJI */ char *targetName = NULL; char *formatName = NULL; + #ifdef KANJI + #define MAX_MULTI_TARGET 3 + int nMultiTarget = 0; + Atom mTarget[MAX_MULTI_TARGET]; + int kanjiCode = TCL_ANY; + char *contentBuf = NULL; + int i; + int result = TCL_ERROR; + #endif /* KANJI */ for (count = argc-2, args = argv+2; count > 1; count -= 2, args += 2) { if (args[0][0] != '-') { *************** *** 484,489 **** --- 497,593 ---- if (tkwin == NULL) { return TCL_ERROR; } + #ifdef KANJI + contentBuf = args[0]; + + if (formatName == NULL) { + /* + * STRING or COMPOUND_TEXT + */ + if (Tcl_KanjiString(interp, contentBuf, NULL, &kanjiCode) == TCL_OK) { + format = Tk_UsefulAtom(tkwin, compoundTextAtom); + } else { + format = XA_STRING; + } + } else { + format = Tk_InternAtom(tkwin, formatName); + } + + if (format == Tk_UsefulAtom(tkwin, compoundTextAtom)) { + /* + * convert to compound text. + */ + wchar *wstr; + int wLen; + if (kanjiCode == TCL_ANY) { + (void)Tcl_KanjiString(interp, contentBuf, NULL, &kanjiCode); + } + if (kanjiCode != TCL_ANY) { + wLen = Tcl_KanjiEncode(kanjiCode, contentBuf, NULL); + wstr = (wchar *)ckalloc((wLen + 1) * sizeof(wchar)); + (void)Tcl_KanjiEncode(kanjiCode, contentBuf, wstr); + contentBuf = Tk_WStrToCtext(wstr, -1); + ckfree((char *)wstr); + } + } + + if (targetName == NULL) { + nMultiTarget = 2; + + /* + * A decent client should use TEXT for selection + * conversion request when it wants text data. + */ + mTarget[0] = Tk_UsefulAtom(tkwin, textAtom); + + if (format == Tk_UsefulAtom(tkwin, compoundTextAtom)) { + /* + * Although above is right, It is not bad client + * asking 'type:COMPOUND_TEXT format:COMPOUND_TEXT'. + * we also prepare for COMPOUND_TEXT request. + */ + mTarget[1] = Tk_UsefulAtom(tkwin, compoundTextAtom); + } else { + /* + * For compatibility reason, preparing for 'type:STRING + * format:STRING' is a practical choice. + */ + mTarget[1] = XA_STRING; + } + } else { + nMultiTarget = 1; + mTarget[0] = Tk_InternAtom(tkwin, targetName); + } + + for (i = 0; i < nMultiTarget; i++) { + result = Tk_ClipboardAppend(interp, tkwin, mTarget[i], format, contentBuf); + if (result != TCL_OK) { + break; + } + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: clip append '%s' as target:'%s' format:'%s'\n", + args[0], + Tk_GetAtomName(tkwin, mTarget[i]), + Tk_GetAtomName(tkwin, format)); + #endif /* SELECTION_DEBUG */ + } + + /* + * Super failsafe!! + * For clients who ONLY knows 'type:STRING format:STRING', add + * this one if it doesn't exist in target array. + */ + if (formatName == NULL && targetName == NULL && format != XA_STRING) { + result = Tk_ClipboardAppend(interp, tkwin, XA_STRING, XA_STRING, args[0]); + #ifdef SELECTION_DEBUG + if (result == TCL_OK) { + fprintf(stderr, "debug: clip append '%s' as target:'%s' format:'%s'\n", + args[0], "STRING", "STRING"); + } + #endif /* SELECTION_DEBUG */ + } + return result; + #else if (targetName != NULL) { target = Tk_InternAtom(tkwin, targetName); } else { *************** *** 495,500 **** --- 599,605 ---- format = XA_STRING; } return Tk_ClipboardAppend(interp, tkwin, target, format, args[0]); + #endif /* KANJI */ } else if ((c == 'c') && (strncmp(argv[1], "clear", length) == 0)) { for (count = argc-2, args = argv+2; count > 0; count -= 2, args += 2) { if (args[0][0] != '-') { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkCmds.c ./generic/tkCmds.c *** ../../tk8.0.5/generic/tkCmds.c Thu Oct 1 04:01:19 1998 --- ./generic/tkCmds.c Fri Mar 12 00:36:45 1999 *************** *** 428,433 **** --- 428,521 ---- } return TCL_OK; } + #ifdef KANJI + + /* + *---------------------------------------------------------------------- + * + * Tk_KanjiInputCmd -- + * + * This procedure is invoked to process the "kanjiInput" Tcl command. + * See the user documentation for details on what it does. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ + int + Tk_KanjiInputCmd(clientData, interp, argc, argv) + ClientData clientData; /* Main window associated with + * interpreter. */ + Tcl_Interp *interp; /* Current interpreter. */ + int argc; /* Number of arguments. */ + char **argv; /* Argument strings. */ + { + Tk_Window tkwin = (Tk_Window) clientData; + Tk_Window winPtr; + unsigned int length; + char c; + + if (argc < 3) { + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " option focusWindow ?arg arg ...?\"", (char *) NULL); + return TCL_ERROR; + } + winPtr = Tk_NameToWindow(interp, argv[2], tkwin); + if (winPtr == NULL ) { + return TCL_ERROR; + } + c = argv[1][0]; + length = strlen(argv[1]); + if ((c == 'a') && (strncmp(argv[1], "attribute", length) == 0)) { + #ifdef KINPUT2 + if (argc == 3) { + return Tk_Kinput2AttributeInfo(interp, winPtr, NULL); + } else if (argc == 4) { + return Tk_Kinput2AttributeInfo(interp, winPtr, argv[3]); + } else { + return Tk_Kinput2Attribute(interp, winPtr, argc-3, argv+3); + } + #else + Tcl_SetResult(interp, "no kanji conversion server supported", TCL_VOLATILE); + return TCL_ERROR; + #endif + } else if ((c == 's') && (strncmp(argv[1], "start", length) == 0)) { + #ifdef KINPUT2 + if (argc == 2) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " start focusWindow ?attributes ...?\"", (char *) NULL); + return TCL_ERROR; + } + return Tk_Kinput2Start(interp, winPtr, argc-3, argv+3); + #else + Tcl_SetResult(interp, "no kanji conversion server supported", TCL_VOLATILE); + return TCL_ERROR; + #endif + } else if ((c == 'e') && (strncmp(argv[1], "end", length) == 0)) { + if (argc != 3) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " end focusWindow\"", (char *) NULL); + return TCL_ERROR; + } + #ifdef KINPUT2 + return Tk_Kinput2End(interp, winPtr); + #else + Tcl_SetResult(interp, "no kanji conversion server supported", TCL_VOLATILE); + return TCL_ERROR; + #endif + } else { + Tcl_AppendResult(interp, "bad option \"", argv[1], + "\": must be start, end, or attribute", (char *) NULL); + return TCL_ERROR; + } + } + #endif /* KANJI */ /* *---------------------------------------------------------------------- diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkConfig.c ./generic/tkConfig.c *** ../../tk8.0.5/generic/tkConfig.c Tue Sep 15 03:23:08 1998 --- ./generic/tkConfig.c Fri Mar 12 00:36:46 1999 *************** *** 374,379 **** --- 374,396 ---- *((char **) ptr) = new; break; } + #ifdef KANJI + case TK_CONFIG_WSTRING: { + wchar *old, *new; + + if (nullValue) { + new = NULL; + } else { + new = Tcl_GetWStr(NULL, value, NULL); + } + old = *((wchar **) ptr); + if (old != NULL) { + Tcl_FreeWStr(old); + } + *((wchar **) ptr) = new; + break; + } + #endif /* KANJI */ case TK_CONFIG_UID: if (nullValue) { *((Tk_Uid *) ptr) = NULL; *************** *** 775,780 **** --- 792,806 ---- result = ""; } break; + #ifdef KANJI + case TK_CONFIG_WSTRING: { + wchar *ws = (*(wchar **) ptr); + if (ws != NULL) { + result = Tcl_DecodeWStr(interp, ws, NULL); + } + break; + } + #endif /* KANJI */ case TK_CONFIG_UID: { Tk_Uid uid = *((Tk_Uid *) ptr); if (uid != NULL) { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkCtext.c ./generic/tkCtext.c *** ../../tk8.0.5/generic/tkCtext.c Thu Jan 1 09:00:00 1970 --- ./generic/tkCtext.c Fri Mar 12 00:36:47 1999 *************** *** 0 **** --- 1,524 ---- + /* + * tkCtext.c -- + * + * This file contains conversion functions between + * wchar and STRING/COMPOUND_TEXT encoding. + * + * Copyright 1988, 1993, 1999 Software Research Associates, Inc. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + */ + + #ifndef lint + static char rcsid[] = "$Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/generic/tkCtext.c,v 1.6 1999/03/11 15:36:47 m-hirano Exp $"; + #endif + + #ifdef KANJI + + #include "tkPort.h" + #include "tkInt.h" + + /* + * Character set flags. Each character set is specified + * with its Final Character and these flags. + * + * CS96 - indicates that the character set is 96 charset. + * otherwise 94. + * MBCS - indicates that the character set is a multibyte + * charset. + */ + #define CS96 0x100 + #define MBCS 0x200 + + static int convJWStoCT _ANSI_ARGS_((wchar *wstr, int len, + unsigned char *xstr)); + static int convCTtoJWS _ANSI_ARGS_((unsigned char *xstr, int len, + wchar *wstr)); + static unsigned char *getesc _ANSI_ARGS_((unsigned char *str, int len)); + static unsigned char *getcsi _ANSI_ARGS_((unsigned char *str, int len)); + + /* + *-------------------------------------------------------------- + * + * Tk_WStrToString -- + * + * Convert wchar string to STRING encoding string. + * Any characters which cannot be converted are ignored. + * + * Results: + * The return value is a pointer to the converted string, + * or NULL if an error occurred in the conversion process. + * The storage for the converted string is allocated with + * malloc (ckalloc, precisely), and it is the caller's + * responsibility to free it. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + char * + Tk_WStrToString(ws, n) + wchar *ws; + int n; + { + int len; + char *s; + int i, j; + + /* if n < 0, count number of characters */ + if (n < 0) { + wchar *t = ws; + n = 0; + while (*t++ != 0) n++; + } + + /* calculate the length of the converted string */ + for (i = 0, len = 0; i < n; i++) { + if ((ws[i] & 0x8080) == 0) len++; /* G0 i.e. ASCII */ + } + + if (len <= 0) return NULL; + s = ckalloc((unsigned int)len + 1); + + /* do the conversion */ + for (i = 0, j = 0; i < n; i++) { + if ((ws[i] & 0x8080) == 0) s[j++] = ws[i] & 0x7f; + } + s[j] = '\0'; + + return s; + } + + /* + *-------------------------------------------------------------- + * + * Tk_WStrToCtext -- + * + * Convert wchar string to Compound Text string. + * + * Results: + * The return value is a pointer to the converted string, + * or NULL if an error occurred in the conversion process. + * The storage for the converted string is allocated with + * malloc (ckalloc, precisely), and it is the caller's + * responsibility to free it. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + char * + Tk_WStrToCtext(ws, n) + wchar *ws; + int n; + { + int len; + char *ct; + + #ifdef __WIN32__ + wchar *tmpws; + if (n < 0) n = Tcl_WStrlen(ws); + tmpws = (wchar *)ckalloc(sizeof(wchar) * (n + 1)); + Tcl_WStrncpy(tmpws, ws, n); + tmpws[n] = 0; + len = Tcl_DecodeSJIS(tmpws, NULL); + ct = ckalloc((unsigned int)len + 1); + Tcl_DecodeSJIS(tmpws, ct); + ckfree((char *) tmpws); + #else + len = convJWStoCT(ws, n, (unsigned char *)NULL); + if (len <= 0) return NULL; + ct = ckalloc((unsigned int)len + 1); + (void)convJWStoCT(ws, n, (unsigned char *)ct); + #endif /* __WIN32__ */ + return ct; + } + + /* + *-------------------------------------------------------------- + * + * Tk_CtextToWStr -- + * + * Convert Compound Text string to wchar string. Any + * characters which cannot be converted are ignored. + * Note that this function can be used to convert STRING + * to wchar string, for Compound Text is a superset of + * STRING. + * + * Results: + * The return value is a pointer to the converted string, + * or NULL if an error occurred in the conversion process. + * The storage for the converted string is allocated with + * malloc (ckalloc, precisely), and it is the caller's + * responsibility to free it. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + wchar * + Tk_CtextToWStr(ct, n) + char *ct; + int n; + { + int len; + wchar *ws; + + #ifdef __WIN32__ + char *tmpct; + if (n < 0) n = strlen(ct); + tmpct = ckalloc(n + 1); + strncpy(tmpct, ct, n); + tmpct[n] = 0; + len = Tcl_EncodeSJIS(tmpct, NULL); + ws = (wchar *)ckalloc(sizeof(wchar) * (unsigned int)(len + 1)); + Tcl_EncodeSJIS(tmpct, ws); + ckfree(tmpct); + #else + len = convCTtoJWS((unsigned char *)ct, n, (wchar *)NULL); + if (len <= 0) return (wchar *)NULL; + ws = (wchar *)ckalloc(sizeof(wchar) * (unsigned int)(len + 1)); + len = convCTtoJWS((unsigned char *)ct, n, ws); + #endif /* __WIN32__ */ + return ws; + } + + /* + *-------------------------------------------------------------- + * + * convJWStoCT -- + * + * Convert Japanese wide character string (type wchar) to + * Compound Text string and returns its length. + * + * Results: + * The return value is the length of the converted string + * (excluding trailing NUL byte). + * The converted string is written in the area specified + * by xstr. It is the caller's responsibility to allocate + * appropriate size of memory for xstr. + * If xstr is NULL, the converted string is not written, + * only the length of the string is returned. So calling + * with xstr NULL is useful for determining the size of + * required storage. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static int + convJWStoCT(wstr, len, xstr) + wchar *wstr; + int len; + unsigned char *xstr; + { + int g1; + int n = 0; + + /* + * G0, G1 usage: + * G0: ASCII + * G1: Kanji or Kana + */ + + /* COMPOUND_TEXT initial value -- ISO8859-1 */ + g1 = CS96|'A'; + + if (len < 0) { + wchar *t = wstr; + len = 0; + while (*t++ != 0) len++; + } + + while (len-- > 0) { + int c = *wstr++; + + switch (c & 0x8080) { + case 0: /* ASCII or C0 or DEL */ + if (c < ' ' || c == 0x7f) { + /* C0 or DEL */ + if (c == '\t' || c == '\n') { + if (xstr) *xstr++ = c; + n++; + } + break; + } + if (xstr) *xstr++ = c & 0x7f; + n++; + break; + case 0x80: /* Kana (JIS-X0201 right half) or C1 */ + if (c < 0xa0 || 0xfe < c) break; + if (g1 != 'I') { + if (xstr) { + *xstr++ = '\033'; + *xstr++ = ')'; + *xstr++ = 'I'; + } + n += 3; + g1 = 'I'; + } + if (xstr) *xstr++ = c & 0xff; + n++; + break; + case 0x8080: /* Kanji (JIS-X0208) */ + if (g1 != (MBCS|'B')) { + if (xstr) { + *xstr++ = '\033'; + *xstr++ = '$'; + *xstr++ = ')'; + *xstr++ = 'B'; + } + n += 4; + g1 = MBCS|'B'; + } + if (xstr) { + *xstr++ = (c >> 8) & 0xff; + *xstr++ = c & 0xff; + } + n += 2; + break; + default: + /* ignore G3 characters (undefined) */ + break; + } + } + + /* + * reset G1 to the default character set + */ + if (g1 != (CS96|'A')) { + if (xstr) { + *xstr++ = '\033'; + *xstr++ = '-'; + *xstr++ = 'A'; + } + n += 3; + } + + if (xstr) *xstr = '\0'; + return n; + } + + /* getesc -- get escape sequence */ + static unsigned char * + getesc(str, len) + unsigned char *str; + int len; + { + int c; + + /* skip intermediate characters: 02/00 - 02/15 */ + while (len > 0) { + c = *str; + if (c < 0x20 || 0x2f < c) break; + len--, str++; + } + /* check final character: 03/00 - 07/14 */ + if (--len < 0 || (c = *str++) < 0x30 || 0x7e < c) { + return (unsigned char *)NULL; + } + return str; + } + + /* getcsi -- get CSI sequence */ + static unsigned char * + getcsi(str, len) + unsigned char *str; + int len; + { + int c; + + /* skip parameter characters: 03/00 - 03/15 */ + while (len > 0) { + c = *str; + if (c < 0x30 || 0x3f < c) break; + len--, str++; + } + /* skip intermediate characters: 02/00 - 02/15 */ + while (len > 0) { + c = *str; + if (c < 0x20 || 0x2f < c) break; + len--, str++; + } + /* check final character: 04/00 - 07/14 */ + if (--len < 0 || (c = *str++) < 0x40 || 0x7e < c) { + return (unsigned char *)NULL; + } + return str; + } + + /* + *-------------------------------------------------------------- + * + * convCTtoJWS -- + * + * Convert Compound Text string to Japanese wide character + * string (type wchar) and returns its length. + * + * Results: + * The return value is the length (the number of characters) + * of the converted string (excluding trailing NUL character). + * The converted string is written in the area specified + * by wstr. It is the caller's responsibility to allocate + * appropriate size of memory for it. + * If wstr is NULL, the converted string is not written, + * only the length of the string is returned. So calling + * with wstr NULL is useful for determining the size of + * required storage. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static int + convCTtoJWS(xstr, len, wstr) + unsigned char *xstr; + int len; + wchar *wstr; + { + int c; + int nskip; + int n = 0; + int g0, g1, gs; + unsigned char *xstr1; + + if (len < 0) len = strlen((char *)xstr); + + /* + * set initial state: + * G0(GL): ASCII + * G1(GR): ISO8859-1 right half + */ + g0 = 'B'; + g1 = CS96|'A'; + + while (len-- > 0) { + switch (c = *xstr++) { + case '\n': case '\t': case ' ': /* NL, TAB, SPACE */ + if (wstr) *wstr++ = c; + n++; + break; + case 0x9b: /* CSI */ + /* + * CSI sequence: in the form of CSI {P} {I} F + * where + * parameter P: 03/00 - 03/15 + * intermediate char I: 02/00 - 02/15 + * final char F: 04/00 - 07/14 + * + * currently, only directionality is defined by + * the Compound Text standard. since Japanese + * doesn't need directionality to be specified, + * ignore all the CSI sequences. + */ + xstr1 = getcsi(xstr, len); + if (xstr1 == NULL) return -1; /* Error */ + len -= xstr1 - xstr; + xstr = xstr1; + break; + case '\033': /* ESC */ + /* + * escape sequence: in the form of ESC {I} F + * where + * intermediate char I: 02/00 - 02/15 + * final char F: 03/00 - 07/14 + * + * currently follwing sequences are defined. + * + statndard character set + * ESC-(-F ESC-)-F ESC---F -- single byte + * ESC-$-(-F ESC-$-)-F -- multi-byte + * + non-standard character set + * ESC-%-/-[0123] + */ + xstr1 = getesc(xstr, len); + if (xstr1 == NULL) return -1; /* Error */ + len -= xstr1 - xstr; + switch (xstr1 - xstr) { + case 2: /* ESC - I - F */ + switch (*xstr++) { + case '(': g0 = *xstr; break; /* 94 CS -> G0 */ + case ')': g1 = *xstr; break; /* 94 CS -> G1 */ + case '-': g1 = *xstr|CS96; break; /* 96 CS -> G1 */ + } + break; + case 3: /* ESC - I - I - F */ + switch (*xstr++) { + case '$': /* Muliti-Byte Character Set */ + switch (*xstr++) { + case '(': g0 = *xstr|MBCS; break; /* 94 MBCS -> G0 */ + case ')': g1 = *xstr|MBCS; break; /* 94 MBCS -> G1 */ + case '-': g1 = *xstr|CS96|MBCS; break; /* 96 MBCS -> G1 */ + } + break; + case '%': + if (*xstr++ != '/') break; /* unknown sequence */ + /* private encoding. skip. */ + len -= 2; + if (len < 0) return -1; + nskip = (*xstr1 & 0x7f) * 128 + (*(xstr1 + 1) & 0x7f); + if ((len -= nskip) < 0) return -1; + xstr1 += nskip + 2; + break; + } + break; + } + xstr = xstr1; + break; + default: + if (!(c & 0x60)) return -1; /* illegal C0 or C1 character */ + + gs = (c & 0x80) ? g1 : g0; + c &= 0x7f; + if (gs & MBCS) { + switch (gs & 0x70) { + case 0x70: /* 4byte/char */ + if (--len < 0) return -1; + c = (c << 8) | (*xstr++ & 0x7f); + case 0x60: /* 3byte/char */ + if (--len < 0) return -1; + c = (c << 8) | (*xstr++ & 0x7f); + case 0x50: /* 2byte/char */ + case 0x40: /* 2byte/char */ + if (--len < 0) return -1; + c = (c << 8) | (*xstr++ & 0x7f); + break; + default: + return -1; + } + } + if (gs == 'B' || gs == 'J' || gs == 'I' || gs == (MBCS|'B')) { + if (wstr) { + switch (gs) { + case MBCS|'B': *wstr++ = c | 0x8080; break; + case 'I': *wstr++ = c | 0x80; break; + default: *wstr++ = c; break; + } + } + n++; + } + break; + } + } + if (wstr) *wstr = 0; + return n; + } + + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkEntry.c ./generic/tkEntry.c *** ../../tk8.0.5/generic/tkEntry.c Tue Sep 15 03:23:09 1998 --- ./generic/tkEntry.c Fri Mar 12 02:39:29 1999 *************** *** 11,19 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkEntry.c,v 1.2 1998/09/14 18:23:09 stanton Exp $ */ #include "tkInt.h" #include "default.h" --- 11,23 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkEntry.c,v 1.11 1999/03/11 17:38:00 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #include "tkInt.h" #include "default.h" *************** *** 36,44 **** /* * Fields that are set by widget commands other than "configure". */ ! char *string; /* Pointer to storage for string; * NULL-terminated; malloc-ed. */ int insertPos; /* Index of character before which next * typed character will be inserted. */ --- 40,53 ---- /* * Fields that are set by widget commands other than "configure". */ ! ! #ifdef TK_KANJI_OK ! wchar *string; /* Pointer to storage for string; ! * NULL-terminated; malloc-ed. */ ! #else char *string; /* Pointer to storage for string; * NULL-terminated; malloc-ed. */ + #endif /* TK_KANJI_OK */ int insertPos; /* Index of character before which next * typed character will be inserted. */ *************** *** 96,104 **** --- 105,119 ---- * characters. */ int selBorderWidth; /* Width of border around selection. */ XColor *selFgColorPtr; /* Foreground color for selected text. */ + #ifdef TK_KANJI_OK + wchar *showChar; /* Value of -show option. If non-NULL, first + * character is used for displaying all + * characters in entry. Malloc'ed. */ + #else char *showChar; /* Value of -show option. If non-NULL, first * character is used for displaying all * characters in entry. Malloc'ed. */ + #endif /* TK_KANJI_OK */ Tk_Uid state; /* Normal or disabled. Entry is read-only * when disabled. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. *************** *** 120,128 **** --- 135,149 ---- int numChars; /* Number of non-NULL characters in * string (may be 0). */ + #ifdef TK_KANJI_OK + wchar *displayString; /* If non-NULL, points to string with same + * length as string but whose characters + * are all equal to showChar. Malloc'ed. */ + #else char *displayString; /* If non-NULL, points to string with same * length as string but whose characters * are all equal to showChar. Malloc'ed. */ + #endif /* TK_KANJI_OK */ int inset; /* Number of pixels on the left and right * sides that are taken up by XPAD, borderWidth * (if any), and highlightWidth (if any). */ *************** *** 248,255 **** --- 269,281 ---- {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background", DEF_ENTRY_SELECT_FG_MONO, Tk_Offset(Entry, selFgColorPtr), TK_CONFIG_MONO_ONLY}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-show", "show", "Show", + DEF_ENTRY_SHOW, Tk_Offset(Entry, showChar), TK_CONFIG_NULL_OK}, + #else {TK_CONFIG_STRING, "-show", "show", "Show", DEF_ENTRY_SHOW, Tk_Offset(Entry, showChar), TK_CONFIG_NULL_OK}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_UID, "-state", "state", "State", DEF_ENTRY_STATE, Tk_Offset(Entry, state), 0}, {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", *************** *** 294,299 **** --- 320,330 ---- int gotFocus)); static int EntryFetchSelection _ANSI_ARGS_((ClientData clientData, int offset, char *buffer, int maxBytes)); + #ifdef TK_KANJI_OK + static int EntryFetchSelectionCtext _ANSI_ARGS_(( + ClientData clientData, + int offset, char *buffer, int maxBytes)); + #endif /* TK_KANJI_OK */ static void EntryLostSelection _ANSI_ARGS_(( ClientData clientData)); static void EventuallyRedraw _ANSI_ARGS_((Entry *entryPtr)); *************** *** 313,318 **** --- 344,353 ---- Tcl_Interp *interp, int argc, char **argv)); static void EntryWorldChanged _ANSI_ARGS_(( ClientData instanceData)); + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + static int EntryXYPos _ANSI_ARGS_((Tcl_Interp *interp, + Entry *entryPtr, int index)); + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ static int GetEntryIndex _ANSI_ARGS_((Tcl_Interp *interp, Entry *entryPtr, char *string, int *indexPtr)); static void InsertChars _ANSI_ARGS_((Entry *entryPtr, int index, *************** *** 384,391 **** --- 419,430 ---- entryPtr->widgetCmd = Tcl_CreateCommand(interp, Tk_PathName(entryPtr->tkwin), EntryWidgetCmd, (ClientData) entryPtr, EntryCmdDeletedProc); + #ifdef TK_KANJI_OK + entryPtr->string = Tcl_GetWStr(NULL, "", NULL); + #else entryPtr->string = (char *) ckalloc(1); entryPtr->string[0] = '\0'; + #endif entryPtr->insertPos = 0; entryPtr->selectFirst = -1; entryPtr->selectLast = -1; *************** *** 441,446 **** --- 480,497 ---- EntryEventProc, (ClientData) entryPtr); Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING, EntryFetchSelection, (ClientData) entryPtr, XA_STRING); + #ifdef TK_KANJI_OK + Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(entryPtr->tkwin, textAtom), + EntryFetchSelectionCtext, + (ClientData) entryPtr, + Tk_UsefulAtom(entryPtr->tkwin, compoundTextAtom)); + Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(entryPtr->tkwin, compoundTextAtom), + EntryFetchSelectionCtext, + (ClientData) entryPtr, + Tk_UsefulAtom(entryPtr->tkwin, compoundTextAtom)); + #endif /* TK_KANJI_OK */ if (ConfigureEntry(interp, entryPtr, argc-2, argv+2, 0) != TCL_OK) { goto error; } *************** *** 560,566 **** --- 611,621 ---- argv[0], " get\"", (char *) NULL); goto error; } + #ifdef TK_KANJI_OK + interp->result = Tcl_DecodeWStr(interp, entryPtr->string, NULL); + #else interp->result = entryPtr->string; + #endif /* TK_KANJI_OK */ } else if ((c == 'i') && (strncmp(argv[1], "icursor", length) == 0) && (length >= 2)) { if (argc != 3) { *************** *** 780,789 **** --- 835,863 ---- entryPtr->flags |= UPDATE_SCROLLBAR; EntryComputeGeometry(entryPtr); EventuallyRedraw(entryPtr); + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + } else if ((c == 'x') && (strncmp(argv[1], "xypos", length) == 0)) { + int index; + + if (argc != 3) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " xypos index\"", + (char *) NULL); + goto error; + } + if (GetEntryIndex(interp, entryPtr, argv[2], &index) != TCL_OK || + EntryXYPos(interp, entryPtr, index) != TCL_OK) { + goto error; + } + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ } else { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be bbox, cget, configure, delete, get, ", + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + "icursor, index, insert, scan, selection, xview, or xypos", + #else "icursor, index, insert, scan, selection, or xview", + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ (char *) NULL); goto error; } *************** *** 826,832 **** --- 900,910 ---- * stuff. */ + #ifdef TK_KANJI_OK + Tcl_FreeWStr(entryPtr->string); + #else ckfree(entryPtr->string); + #endif /* TK_KANJI_OK */ if (entryPtr->textVarName != NULL) { Tcl_UntraceVar(entryPtr->interp, entryPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, *************** *** 840,846 **** --- 918,928 ---- } Tcl_DeleteTimerHandler(entryPtr->insertBlinkHandler); if (entryPtr->displayString != NULL) { + #ifdef TK_KANJI_OK + ckfree((char *) entryPtr->displayString); + #else ckfree(entryPtr->displayString); + #endif /* TK_KANJI_OK */ } Tk_FreeTextLayout(entryPtr->textLayout); Tk_FreeOptions(configSpecs, (char *) entryPtr, entryPtr->display, 0); *************** *** 1003,1009 **** --- 1085,1098 ---- entryPtr = (Entry *) instanceData; + #ifdef TK_KANJI_OK + { + wchar wTmp = '0'; + entryPtr->avgWidth = Tk_TextWidth(entryPtr->tkfont, &wTmp, 1); + } + #else entryPtr->avgWidth = Tk_TextWidth(entryPtr->tkfont, "0", 1); + #endif /* TK_KANJI_OK */ if (entryPtr->avgWidth == 0) { entryPtr->avgWidth = 1; } *************** *** 1264,1270 **** --- 1353,1363 ---- int totalLength, overflow, maxOffScreen, rightX; int height, width, i; Tk_FontMetrics fm; + #ifdef TK_KANJI_OK + wchar *p, *displayString; + #else char *p, *displayString; + #endif /* TK_KANJI_OK */ /* * If we're displaying a special character instead of the value of *************** *** 1272,1283 **** --- 1365,1385 ---- */ if (entryPtr->displayString != NULL) { + #ifdef TK_KANJI_OK + ckfree((char *) entryPtr->displayString); + #else ckfree(entryPtr->displayString); + #endif /* TK_KANJI_OK */ entryPtr->displayString = NULL; } if (entryPtr->showChar != NULL) { + #ifdef TK_KANJI_OK + entryPtr->displayString = + (wchar *) ckalloc(sizeof(wchar) * ((unsigned)(entryPtr->numChars + 1))); + #else entryPtr->displayString = (char *) ckalloc((unsigned) (entryPtr->numChars + 1)); + #endif /* TK_KANJI_OK */ for (p = entryPtr->displayString, i = entryPtr->numChars; i > 0; i--, p++) { *p = entryPtr->showChar[0]; *************** *** 1377,1382 **** --- 1479,1494 ---- * string). */ { int length; + #ifdef TK_KANJI_OK + wchar *wstr; + + wstr = Tcl_GetWStr(NULL, string, NULL); + length = Tcl_WStrlen(wstr); + if( length == 0 ) return; + entryPtr->string = Tcl_InsertWStr(entryPtr->interp, + entryPtr->string, index, wstr); + Tcl_FreeWStr(wstr); + #else char *new; length = strlen(string); *************** *** 1389,1394 **** --- 1501,1507 ---- strcpy(new+index+length, entryPtr->string+index); ckfree(entryPtr->string); entryPtr->string = new; + #endif /* TK_KANJI_OK */ entryPtr->numChars += length; /* *************** *** 1440,1446 **** --- 1553,1561 ---- int index; /* Index of first character to delete. */ int count; /* How many characters to delete. */ { + #ifndef TK_KANJI_OK char *new; + #endif /* TK_KANJI_OK */ if ((index + count) > entryPtr->numChars) { count = entryPtr->numChars - index; *************** *** 1449,1459 **** --- 1564,1579 ---- return; } + #ifdef TK_KANJI_OK + entryPtr->string = Tcl_DeleteWStr(entryPtr->interp, entryPtr->string, + index, count); + #else new = (char *) ckalloc((unsigned) (entryPtr->numChars + 1 - count)); strncpy(new, entryPtr->string, (size_t) index); strcpy(new+index, entryPtr->string+index+count); ckfree(entryPtr->string); entryPtr->string = new; + #endif /* TK_KANJI_OK */ entryPtr->numChars -= count; /* *************** *** 1527,1541 **** --- 1647,1672 ---- Entry *entryPtr; /* Entry whose value just changed. */ { char *newValue; + #ifdef TK_KANJI_OK + char *str = Tcl_DecodeWStr(entryPtr->interp, entryPtr->string, NULL); + #endif /* TK_KANJI_OK */ if (entryPtr->textVarName == NULL) { newValue = NULL; } else { newValue = Tcl_SetVar(entryPtr->interp, entryPtr->textVarName, + #ifdef TK_KANJI_OK + str, TCL_GLOBAL_ONLY); + #else entryPtr->string, TCL_GLOBAL_ONLY); + #endif /* TK_KANJI_OK */ } + #ifdef TK_KANJI_OK + if ((newValue != NULL) && (strcmp(newValue, str) != 0)) { + #else if ((newValue != NULL) && (strcmp(newValue, entryPtr->string) != 0)) { + #endif /* TK_KANJI_OK */ /* * The value of the variable is different than what we asked for. * This means that a trace on the variable modified it. In this *************** *** 1584,1593 **** --- 1715,1732 ---- * changed. */ char *value; /* New text to display in entry. */ { + #ifdef TK_KANJI_OK + wchar *old = entryPtr->string; + + entryPtr->string = Tcl_GetWStr(NULL, value, NULL); + entryPtr->numChars = Tcl_WStrlen(entryPtr->string); + Tcl_FreeWStr(old); + #else ckfree(entryPtr->string); entryPtr->numChars = strlen(value); entryPtr->string = (char *) ckalloc((unsigned) (entryPtr->numChars + 1)); strcpy(entryPtr->string, value); + #endif /* TK_KANJI_OK */ if (entryPtr->selectFirst != -1) { if (entryPtr->selectFirst >= entryPtr->numChars) { entryPtr->selectFirst = entryPtr->selectLast = -1; *************** *** 1967,1984 **** --- 2106,2147 ---- { Entry *entryPtr = (Entry *) clientData; int count; + #ifdef TK_KANJI_OK + char *str; + wchar *displayString; + #else char *displayString; + #endif /* TK_KANJI_OK */ if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { return -1; } + #ifdef TK_KANJI_OK + if (entryPtr->displayString == NULL) { + displayString = entryPtr->string; + } else { + displayString = entryPtr->displayString; + } + count = entryPtr->selectLast - entryPtr->selectFirst; + str = Tk_WStrToString(displayString + entryPtr->selectFirst, count); + if (str == NULL) return 0; + count = strlen(str) - offset; + #else count = entryPtr->selectLast - entryPtr->selectFirst - offset; + #endif /* TK_KANJI_OK */ if (count > maxBytes) { count = maxBytes; } if (count <= 0) { + #ifdef TK_KANJI_OK + ckfree(str); + #endif /* TK_KANJI_OK */ return 0; } + #ifdef TK_KANJI_OK + strncpy(buffer, str + offset, (size_t) count); + ckfree(str); + #else if (entryPtr->displayString == NULL) { displayString = entryPtr->string; } else { *************** *** 1986,1994 **** --- 2149,2219 ---- } strncpy(buffer, displayString + entryPtr->selectFirst + offset, (size_t) count); + #endif /* TK_KANJI_OK */ + buffer[count] = '\0'; + return count; + } + #ifdef TK_KANJI_OK + + /* + *---------------------------------------------------------------------- + * + * EntryFetchSelectionCtext -- + * + * This procedure is same as EntryFetchSelection except it + * converts the selection data to compound text encoding. + * + * Results: + * See EntryFetchSelection. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + static int + EntryFetchSelectionCtext(clientData, offset, buffer, maxBytes) + ClientData clientData; /* Information about entry widget. */ + int offset; /* Offset within selection of first + * character to be returned. */ + char *buffer; /* Location in which to place + * selection. */ + int maxBytes; /* Maximum number of bytes to place + * at buffer, not including terminating + * NULL character. */ + { + Entry *entryPtr = (Entry *) clientData; + int count; + char *str; + wchar *displayString; + + if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { + return -1; + } + if (entryPtr->displayString == NULL) { + displayString = entryPtr->string; + } else { + displayString = entryPtr->displayString; + } + count = entryPtr->selectLast - entryPtr->selectFirst; + str = Tk_WStrToCtext(displayString + entryPtr->selectFirst, count); + if (str == NULL) return 0; + + count = strlen(str) - offset; + if (count > maxBytes) { + count = maxBytes; + } + if (count <= 0) { + ckfree(str); + return 0; + } + strncpy(buffer, str + offset, (size_t) count); + ckfree(str); buffer[count] = '\0'; return count; } + #endif /* TK_KANJI_OK */ /* *---------------------------------------------------------------------- *************** *** 2278,2283 **** --- 2503,2511 ---- { register Entry *entryPtr = (Entry *) clientData; char *value; + #ifdef TK_KANJI_OK + wchar *wstr; + #endif /* TK_KANJI_OK */ /* * If the variable is unset, then immediately recreate it unless *************** *** 2286,2293 **** --- 2514,2527 ---- if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { + #ifdef TK_KANJI_OK + Tcl_SetVar(interp, entryPtr->textVarName, + Tcl_DecodeWStr(entryPtr->interp, entryPtr->string, NULL), + TCL_GLOBAL_ONLY); + #else Tcl_SetVar(interp, entryPtr->textVarName, entryPtr->string, TCL_GLOBAL_ONLY); + #endif /* TK_KANJI_OK */ Tcl_TraceVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, EntryTextVarProc, clientData); *************** *** 2306,2313 **** --- 2540,2622 ---- if (value == NULL) { value = ""; } + #ifdef TK_KANJI_OK + wstr = Tcl_GetWStr(NULL, value, NULL); + if (Tcl_WStrcmp(wstr, entryPtr->string) != 0) { + EntrySetValue(entryPtr, value); + } + Tcl_FreeWStr(wstr); + #else if (strcmp(value, entryPtr->string) != 0) { EntrySetValue(entryPtr, value); } + #endif /* TK_KANJI_OK */ return (char *) NULL; } + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + + /* + *-------------------------------------------------------------- + * + * EntryXYPos -- + * + * This procedure returns XY coordinates of the point + * specified by its index. The Y coordinate is of + * the baseline. + * + * Results: + * The return value is always TCL_OK (i.e. no errors possible). + * If the point is visible, this procedure will return a list + * containing its X and Y position. Othewise, an empty string + * will be returned. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static int + EntryXYPos(interp, entryPtr, index) + Tcl_Interp *interp; /* For the result */ + Entry *entryPtr; /* Entry for which the index is being + * specified. */ + int index; /* Character index for which its position + * is to be retrieved. */ + { + Tk_Window tkwin = entryPtr->tkwin; + int leftidx = entryPtr->leftIndex; + int posX, posY; + int nchars; + + if (entryPtr->tkwin != NULL && Tk_IsMapped(tkwin) && index >= leftidx) { + Tk_FontMetrics fm; + + /* + * Compute X-coordinate of the "index" character + */ + + if (index == leftidx) { + posX = entryPtr->inset; + } else { + nchars = Tk_MeasureChars(entryPtr->tkfont, + entryPtr->string + leftidx, + index - leftidx, + Tk_Width(tkwin) - entryPtr->inset, + TK_PARTIAL_OK, + &posX); + posX += entryPtr->inset; + if (nchars < index - leftidx) return TCL_OK; + } + + /* + * Y-coordinate is of the baseline + */ + Tk_GetFontMetrics(entryPtr->tkfont, &fm); + posY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2; + sprintf(interp->result, "%d %d", posX, posY); + } + + return TCL_OK; + } + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkEvent.c ./generic/tkEvent.c *** ../../tk8.0.5/generic/tkEvent.c Sat Oct 10 09:30:36 1998 --- ./generic/tkEvent.c Mon May 10 19:10:15 1999 *************** *** 584,589 **** --- 584,608 ---- } #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + /* + * We should NOT call XCreateIC() here. + * Instead, call XCreateIC() when the application REALLY need IM session + * like in text widget, entry widget or whatever widget the user want to + * use IM in it. To enable this, I add "imconfigure" command. + * Furthermore, not call XFilterEvent() here. We should call + * XFilterEvent() before the event will be enqueued. + * I do it in tkUnixEvent.c. + */ + #if 0 + if ((winPtr->flags & TK_CHECKED_IC) && + (winPtr->inputContext != NULL)) { + if (XFilterEvent(eventPtr, None)) { + goto done; + } + } + #endif + #else /* * Pass the event to the input method(s), if there are any, and * discard the event if the input method(s) insist. Create the *************** *** 604,609 **** --- 623,629 ---- if (XFilterEvent(eventPtr, None)) { goto done; } + #endif /* XIM_IMPROVE */ #endif /* TK_USE_INPUT_METHODS */ /* *************** *** 849,854 **** --- 869,890 ---- break; } } + + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + #ifdef XIM_DEBUG + DumpXEvent(dispPtr->display, eventPtr); + #endif /* XIM_DEBUG */ + if (eventPtr->type == KeyPress && eventPtr->xkey.keycode == 0) { + /* + * No doubt this is a composed message from IM server. + * Tk can handle KeyPress event with zero keycode value + * if state of the event is zero. + */ + eventPtr->xkey.state = 0; + } + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ if ((dispPtr->delayedMotionPtr != NULL) && (position == TCL_QUEUE_TAIL)) { if ((eventPtr->type == MotionNotify) && (eventPtr->xmotion.window diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkFont.c ./generic/tkFont.c *** ../../tk8.0.5/generic/tkFont.c Tue Sep 15 03:23:10 1998 --- ./generic/tkFont.c Mon May 10 19:10:16 1999 *************** *** 33,38 **** --- 33,42 ---- * Tk_Uids, values are NamedFont structs. */ TkMainInfo *mainPtr; /* Application that owns this structure. */ int updatePending; + #ifdef KANJI + int doCompoundPrefetch; /* if 1, prefetch compound font at + * creation time. */ + #endif /* KANJI */ } TkFontInfo; /* *************** *** 150,155 **** --- 154,163 ---- {TK_FW_BOLD, "bold"}, {TK_FW_BOLD, "demi"}, {TK_FW_BOLD, "demibold"}, + #ifdef KANJI + {TK_FW_BOLD, "black"}, + {TK_FW_NORMAL, "regular"}, + #endif /* KANJI */ {TK_FW_NORMAL, NULL} /* Assume anything else is "normal". */ }; *************** *** 172,177 **** --- 180,188 ---- {TK_CS_NORMAL, "iso8859"}, {TK_CS_SYMBOL, "adobe"}, {TK_CS_SYMBOL, "sun"}, + #ifdef KANJI + {TK_CS_KANJI, "jisx0208.1983"}, + #endif /* KANJI */ {TK_CS_OTHER, NULL} }; *************** *** 181,195 **** --- 192,227 ---- */ static char *fontOpt[] = { + #ifdef KANJI + "-foundry", + #endif /* KANJI */ "-family", "-size", "-weight", "-slant", "-underline", "-overstrike", + #ifdef KANJI + "-charset", + "-pointadjust", + "-compound", + #endif /* KANJI */ NULL }; + #ifdef KANJI + #define FONT_FOUNDRY 0 + #define FONT_FAMILY 1 + #define FONT_SIZE 2 + #define FONT_WEIGHT 3 + #define FONT_SLANT 4 + #define FONT_UNDERLINE 5 + #define FONT_OVERSTRIKE 6 + #define FONT_CHARSET 7 + #define FONT_POINTADJUST 8 + #define FONT_COMPOUND 9 + #define FONT_NUMFIELDS 10 /* Length of fontOpt array. */ + #else #define FONT_FAMILY 0 #define FONT_SIZE 1 #define FONT_WEIGHT 2 *************** *** 197,202 **** --- 229,256 ---- #define FONT_UNDERLINE 4 #define FONT_OVERSTRIKE 5 #define FONT_NUMFIELDS 6 /* Length of fontOpt array. */ + #endif /* KANJI */ + + #ifdef KANJI + /* + * Default font package + */ + typedef struct { + Tk_Uid fontName; + Tk_Font tkfont; + } TkDefaultFont; + + static Tcl_HashTable *defaultFontTab = NULL; + static Tcl_HashTable *displayInitTab = NULL; + + static TkDefaultFont *AllocDefaultFont _ANSI_ARGS_((Tk_Window tkwin, char *name)); + static void DeleteDefaultFont _ANSI_ARGS_((TkDefaultFont *dFontPtr)); + static int SetDefaultFont _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, char *name)); + static char * GetDefaultFontName _ANSI_ARGS_((Tk_Window tkwin)); + static void TheDefaultFontHasChanged _ANSI_ARGS_((ClientData clientData)); + static void RecomputeWidgetsOnDisplay _ANSI_ARGS_((TkWindow *winPtr, Display *dpy)); + #endif /* KANJI */ #define GetFontAttributes(tkfont) \ ((CONST TkFontAttributes *) &((TkFont *) (tkfont))->fa) *************** *** 208,213 **** --- 262,272 ---- static int ConfigAttributesObj _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[], TkFontAttributes *faPtr)); + #ifdef KANJI + static int ConfigCompoundAttributesObj _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[], + TkFontAttributes *faPtr)); + #endif /* KANJI */ static int FieldSpecified _ANSI_ARGS_((CONST char *field)); static int GetAttributeInfoObj _ANSI_ARGS_((Tcl_Interp *interp, CONST TkFontAttributes *faPtr, Tcl_Obj *objPtr)); *************** *** 223,229 **** static void UpdateDependantFonts _ANSI_ARGS_((TkFontInfo *fiPtr, Tk_Window tkwin, Tcl_HashEntry *namedHashPtr)); ! /* --- 282,288 ---- static void UpdateDependantFonts _ANSI_ARGS_((TkFontInfo *fiPtr, Tk_Window tkwin, Tcl_HashEntry *namedHashPtr)); ! /* *************** *** 255,260 **** --- 314,322 ---- Tcl_InitHashTable(&fiPtr->namedTable, TCL_ONE_WORD_KEYS); fiPtr->mainPtr = mainPtr; fiPtr->updatePending = 0; + #ifdef KANJI + fiPtr->doCompoundPrefetch = 0; + #endif /* KANJI */ mainPtr->fontInfoPtr = fiPtr; } *************** *** 283,288 **** --- 345,353 ---- TkFontInfo *fiPtr; Tcl_HashEntry *hPtr; Tcl_HashSearch search; + #ifdef KANJI + NamedFont *nfPtr = NULL; + #endif /* KANJI */ fiPtr = mainPtr->fontInfoPtr; *************** *** 293,299 **** --- 358,377 ---- hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); while (hPtr != NULL) { + #ifdef KANJI + nfPtr = (NamedFont *)Tcl_GetHashValue(hPtr); + if (nfPtr->fa.fontType == TK_FONT_COMPOUND) { + if (nfPtr->fa.asciiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.asciiFaPtr); + } + if (nfPtr->fa.kanjiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.kanjiFaPtr); + } + } + ckfree((char *)nfPtr); + #else ckfree((char *) Tcl_GetHashValue(hPtr)); + #endif /* KANJI */ hPtr = Tcl_NextHashEntry(&search); } Tcl_DeleteHashTable(&fiPtr->namedTable); *************** *** 330,335 **** --- 408,425 ---- int index; Tk_Window tkwin; TkFontInfo *fiPtr; + #ifdef KANJI + static char *optionStrings[] = { + "actual", "cache", "configure", "create", + "delete", "failsafe", "families", "measure", + "metrics", "names", "prefetch", NULL + }; + enum options { + FONT_ACTUAL, FONT_CACHE, FONT_CONFIGURE, FONT_CREATE, + FONT_DELETE, FONT_FAILSAFE, FONT_FAMILIES, FONT_MEASURE, + FONT_METRICS, FONT_NAMES, FONT_PREFETCH + }; + #else static char *optionStrings[] = { "actual", "configure", "create", "delete", "families", "measure", "metrics", "names", *************** *** 339,344 **** --- 429,435 ---- FONT_ACTUAL, FONT_CONFIGURE, FONT_CREATE, FONT_DELETE, FONT_FAMILIES, FONT_MEASURE, FONT_METRICS, FONT_NAMES }; + #endif /* KANJI */ tkwin = (Tk_Window) clientData; fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; *************** *** 383,388 **** --- 474,520 ---- Tk_FreeFont(tkfont); return result; } + #ifdef KANJI + case FONT_CACHE: { + Tk_Window dpyTkWin = tkwin; + int skip; + char *cmd = NULL; + int doClear = 0; + + if (objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-displayof window? ?clear?"); + return TCL_ERROR; + } + skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &dpyTkWin); + if (skip < 0) { + return TCL_ERROR; + } else if (skip == 0) { + skip = objc - 1; + } else { + skip = objc - 2 + skip - 1; + } + if (dpyTkWin == tkwin) { + dpyTkWin = NULL; + } + + if (skip > 1 && skip < objc) { + cmd = Tcl_GetStringFromObj(objv[skip], NULL); + if (cmd != NULL) { + if (strcmp(cmd, "clear") == 0) { + doClear = 1; + } else if (strcmp(cmd, "dump") == 0) { + doClear = -1; + } + } + } + #ifdef __WIN32__ /* do nothing */ + return TCL_OK; + #else + return TkpFreeFontCache(interp, dpyTkWin, doClear); + #endif /* __WIN32__ */ + } + #endif /* KANJI */ case FONT_CONFIGURE: { int result; char *string; *************** *** 412,418 **** --- 544,623 ---- } else { result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3, &nfPtr->fa); + #ifdef KANJI + if (nfPtr->fa.fontType != TK_FONT_COMPOUND) { + Tcl_HashSearch search; + Tcl_HashEntry *hPtr = NULL; + Tcl_HashEntry *fcPtr = NULL; + NamedFont *pNfPtr = NULL; + int found = 0; + TkFont *tkfont = NULL; + CachedFontKey aKey; + + hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); + while (hPtr != NULL) { + pNfPtr = (NamedFont *)Tcl_GetHashValue(hPtr); + if (pNfPtr == nfPtr) { + goto endLoop; + } + if (pNfPtr->fa.asciiFontName == string) { + memcpy((VOID *)pNfPtr->fa.asciiFaPtr, (VOID *)&nfPtr->fa, + sizeof(TkFontAttributes)); + #ifdef __WIN32__ + /* Don't reflect underline and overstrike. */ + pNfPtr->fa.asciiFaPtr->underline = pNfPtr->fa.underline; + pNfPtr->fa.asciiFaPtr->overstrike = pNfPtr->fa.overstrike; + #endif + } else if (pNfPtr->fa.kanjiFontName == string) { + memcpy((VOID *)pNfPtr->fa.kanjiFaPtr, (VOID *)&nfPtr->fa, + sizeof(TkFontAttributes)); + #ifdef __WIN32__ + /* Don't reflect underline and overstrike. */ + pNfPtr->fa.kanjiFaPtr->underline = pNfPtr->fa.underline; + pNfPtr->fa.kanjiFaPtr->overstrike = pNfPtr->fa.overstrike; + #endif + } else { + goto endLoop; + } + if (pNfPtr->refCount <= 0) { + goto endLoop; + } + + found++; + aKey.display = Tk_Display(tkwin); + aKey.string = Tcl_GetHashKey(&fiPtr->namedTable, hPtr); + if (aKey.string == NULL) { + panic("Why?? Named font not in nameTable (key NULL)"); + } + fcPtr = Tcl_FindHashEntry(&fiPtr->fontCache, (char *)&aKey); + if (fcPtr == NULL) { + panic("Why?? Named font not in fontCache (entry NULL)"); + } + tkfont = (TkFont *)Tcl_GetHashValue(fcPtr); + if (tkfont == NULL) { + found--; + goto endLoop; + } + TkpGetFontFromAttributes(tkfont, tkwin, &pNfPtr->fa); + + endLoop: + hPtr = Tcl_NextHashEntry(&search); + } + + if (found > 0) { + if (fiPtr->updatePending == 0) { + fiPtr->updatePending = 1; + Tcl_DoWhenIdle(TheWorldHasChanged, (ClientData)fiPtr); + } + } else { + UpdateDependantFonts(fiPtr, tkwin, namedHashPtr); + } + } else { + UpdateDependantFonts(fiPtr, tkwin, namedHashPtr); + } + #else UpdateDependantFonts(fiPtr, tkwin, namedHashPtr); + #endif /* KANJI */ return result; } return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); *************** *** 429,437 **** --- 634,654 ---- name = NULL; } else { name = Tcl_GetStringFromObj(objv[2], NULL); + #ifdef KANJI + for (i = 0; i < FONT_NUMFIELDS; i++) { + if (strcmp(fontOpt[i], name) == 0) { + name = NULL; + break; + } + } + if (name != NULL && strncmp("-copy", name, 5) == 0) { + name = NULL; + } + #else if (name[0] == '-') { name = NULL; } + #endif /* KANJI */ } if (name == NULL) { /* *************** *** 450,455 **** --- 667,845 ---- skip = 2; } TkInitFontAttributes(&fa); + #ifdef KANJI + if ((objv[skip] != NULL) && + (!strcmp(Tcl_GetStringFromObj(objv[skip], NULL), "-compound"))) { + int numFonts; + char **fontNames; + Tk_Font ascii = NULL; + Tk_Font kanji = NULL; + Tk_Font tmp; + Tk_Uid tmpName; + char compoundName[1024]; + + skip++; + + if (objv[skip] == NULL) { + Tcl_WrongNumArgs(interp, objc, objv, + "create ?fontname? -compound fontlist ?options?"); + return TCL_ERROR; + } + if (Tcl_SplitList(interp, Tcl_GetStringFromObj(objv[skip], NULL), + &numFonts, &fontNames) != TCL_OK) { + return TCL_ERROR; + } + /* + * Currently, ascii and kanji only. + */ + #define MAX_COMPOUND 2 + if (numFonts > MAX_COMPOUND) numFonts = MAX_COMPOUND; + + for (i = 0; i < numFonts; i++) { + tmpName = Tk_GetUid(fontNames[i]); + tmp = Tk_GetFont(interp, tkwin, tmpName); + if (tmp == NULL) { + Tcl_Free((char *)fontNames); + return TCL_ERROR; + } + if (Tk_FontType(tmp) == TK_FONT_COMPOUND) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "font \"", tmpName, + "\" is already compounded.", NULL); + Tcl_Free((char *)fontNames); + Tk_FreeFont(tmp); + return TCL_ERROR; + } else if (Tk_FontType(tmp) == TK_FONT_GENERIC) { + if (ascii == NULL) { + ascii = tmp; + fa.asciiFontName = tmpName; + } else { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "ascii font is alread specified.", NULL); + Tcl_Free((char *)fontNames); + Tk_FreeFont(tmp); + Tk_FreeFont(ascii); + return TCL_ERROR; + } + } else if (Tk_FontType(tmp) == TK_FONT_2BYTES) { + if (kanji == NULL) { + kanji = tmp; + fa.kanjiFontName = tmpName; + } else { + #ifdef __WIN32__ + /* assume {ascii kanji} order */ + ascii = kanji; + fa.asciiFontName = fa.kanjiFontName; + kanji = tmp; + fa.kanjiFontName = tmpName; + #else + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "kanji font is alread specified.", NULL); + Tcl_Free((char *)fontNames); + Tk_FreeFont(tmp); + Tk_FreeFont(kanji); + return TCL_ERROR; + #endif /* __WIN32__ */ + } + } else { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "Can't handle the charset of font \"", + tmpName, "\".", NULL); + Tcl_Free((char *)fontNames); + Tk_FreeFont(tmp); + return TCL_ERROR; + } + } + + if (ascii == NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "ascii font is not specified.", NULL); + if (kanji != NULL) { + Tk_FreeFont(kanji); + } + Tcl_Free((char *)fontNames); + return TCL_ERROR; + } + if (kanji == NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "2 bytes font is not specified.", NULL); + if (ascii != NULL) { + Tk_FreeFont(ascii); + } + Tcl_Free((char *)fontNames); + return TCL_ERROR; + } + + sprintf(compoundName, "%s:%s", + (Tk_FontFoundry(ascii) == NULL) ? "{}" : Tk_FontFoundry(ascii), + (Tk_FontFoundry(kanji) == NULL) ? "{}" : Tk_FontFoundry(kanji)); + fa.foundry = Tk_GetUid(compoundName); + sprintf(compoundName, "%s:%s", Tk_FontFamily(ascii), Tk_FontFamily(kanji)); + fa.family = Tk_GetUid(compoundName); + sprintf(compoundName, "%s:%s", Tk_FontCharset(ascii), Tk_FontCharset(kanji)); + fa.charset = Tk_GetUid(compoundName); + fa.fontType = TK_FONT_COMPOUND; + fa.pointsize = Tk_FontSize(kanji); + if (fa.pointsize < 0) { + fa.pointsize = TkpConvertPixelToPoint(tkwin, -(fa.pointsize)); + } + { + int aP = Tk_FontSize(ascii); + if (aP < 0) { + aP = TkpConvertPixelToPoint(tkwin, -aP); + } + fa.pointAdjust = (double)((double)aP / (double)fa.pointsize); + } + /* + * OK now, copy attribute of the each fonts, and free the fonts. + */ + fa.asciiFaPtr = (TkFontAttributes *)ckalloc(sizeof(TkFontAttributes)); + fa.kanjiFaPtr = (TkFontAttributes *)ckalloc(sizeof(TkFontAttributes)); + memcpy((VOID *)(fa.asciiFaPtr), (VOID *)GetFontAttributes(ascii), + sizeof(TkFontAttributes)); + memcpy((VOID *)(fa.kanjiFaPtr), (VOID *)GetFontAttributes(kanji), + sizeof(TkFontAttributes)); + #ifdef __WIN32__ + /* Ignore descendant's underline and overstrike attributes. */ + fa.asciiFaPtr->underline = fa.kanjiFaPtr->underline = 0; + fa.asciiFaPtr->overstrike = fa.kanjiFaPtr->overstrike = 0; + #endif + Tk_FreeFont(ascii); + Tk_FreeFont(kanji); + Tcl_Free((char *)fontNames); + skip++; + } else if ((objv[skip] != NULL) && + (!strcmp(Tcl_GetStringFromObj(objv[skip], NULL), "-copy"))) { + Tk_Font copy; + + skip++; + + if (objv[skip] == NULL) { + Tcl_WrongNumArgs(interp, objc, objv, + "create ?fontname? -copy fontname ?options?"); + return TCL_ERROR; + } + copy = Tk_GetFontFromObj(interp, tkwin, objv[skip]); + if (copy == NULL) { + return TCL_ERROR; + } + memcpy((VOID *)&fa, (VOID *)GetFontAttributes(copy), + sizeof(TkFontAttributes)); + if (Tk_FontType(copy) == TK_FONT_COMPOUND) { + /* + * copy attribute of descendant fonts. + */ + TkFontAttributes *aFaPtr = (TkFontAttributes *)ckalloc(sizeof(TkFontAttributes)); + TkFontAttributes *kFaPtr = (TkFontAttributes *)ckalloc(sizeof(TkFontAttributes)); + memcpy((VOID *)(aFaPtr), (VOID *)fa.asciiFaPtr, sizeof(TkFontAttributes)); + memcpy((VOID *)(kFaPtr), (VOID *)fa.kanjiFaPtr, sizeof(TkFontAttributes)); + fa.asciiFaPtr = aFaPtr; + fa.kanjiFaPtr = kFaPtr; + } + Tk_FreeFont(copy); + skip++; + } + #endif /* KANJI */ if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip, &fa) != TCL_OK) { return TCL_ERROR; *************** *** 457,462 **** --- 847,862 ---- if (TkCreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) { return TCL_ERROR; } + #ifdef KANJI + if (fa.fontType == TK_FONT_COMPOUND && + fiPtr->doCompoundPrefetch == 1) { + /* + * Prefetch font. This makes descendant fonts + * be loaded on UNIX. + */ + TkpDeleteFont(TkpGetFontFromAttributes(NULL, tkwin, &fa)); + } + #endif /* KANJI */ Tcl_SetStringObj(Tcl_GetObjResult(interp), name, -1); break; } *************** *** 488,493 **** --- 888,903 ---- nfPtr->deletePending = 1; } else { Tcl_DeleteHashEntry(namedHashPtr); + #ifdef KANJI + if (nfPtr->fa.fontType == TK_FONT_COMPOUND) { + if (nfPtr->fa.asciiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.asciiFaPtr); + } + if (nfPtr->fa.kanjiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.kanjiFaPtr); + } + } + #endif /* KANJI */ ckfree((char *) nfPtr); } } *************** *** 507,512 **** --- 917,950 ---- TkpGetFontFamilies(interp, tkwin); break; } + #ifdef KANJI + case FONT_FAILSAFE: { + Tk_Window dpyTkWin = tkwin; + char *string = NULL; + int skip; + + if (objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-displayof window? ?nativefont?"); + return TCL_ERROR; + } + skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &dpyTkWin); + if (skip < 0) { + return TCL_ERROR; + } + skip += 2; + if (skip < objc) { + string = Tcl_GetStringFromObj(objv[skip], NULL); + if (SetDefaultFont(interp, dpyTkWin, string) != TCL_OK) { + return TCL_ERROR; + } + } else { + string = GetDefaultFontName(dpyTkWin); + } + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), string, NULL); + break; + } + #endif /* KANJI */ case FONT_MEASURE: { char *string; Tk_Font tkfont; *************** *** 526,532 **** --- 964,979 ---- return TCL_ERROR; } string = Tcl_GetStringFromObj(objv[3 + skip], &length); + #ifdef KANJI + { + wchar *wTmp = Tcl_GetWStr(NULL, string, NULL); + length = Tcl_WStrlen(wTmp); + Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_WTextWidth(tkfont, wTmp, length)); + Tcl_FreeWStr(wTmp); + } + #else Tcl_SetIntObj(Tcl_GetObjResult(interp), Tk_TextWidth(tkfont, string, length)); + #endif /* KANJI */ Tk_FreeFont(tkfont); break; } *************** *** 603,608 **** --- 1050,1071 ---- } break; } + #ifdef KANJI + case FONT_PREFETCH: { + if (objc >= 3) { + if (Tcl_GetBooleanFromObj(interp, objv[2], + &fiPtr->doCompoundPrefetch) != TCL_OK) { + return TCL_ERROR; + } + } + if (fiPtr->doCompoundPrefetch == 1) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "yes", NULL); + } else { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "no", NULL); + } + break; + } + #endif /* KANJI */ } return TCL_OK; } *************** *** 670,675 **** --- 1133,1141 ---- fiPtr = (TkFontInfo *) clientData; fiPtr->updatePending = 0; + #ifdef COMPOUND_DEBUG + fprintf(stderr, "\n\nWorld Changed !!\n\n"); + #endif RecomputeWidgets(fiPtr->mainPtr->winPtr); } *************** *** 743,748 **** --- 1209,1224 ---- * font, so they need to get redisplayed. */ + #ifdef KANJI + if (nfPtr->fa.fontType == TK_FONT_COMPOUND) { + if (nfPtr->fa.asciiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.asciiFaPtr); + } + if (nfPtr->fa.kanjiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.kanjiFaPtr); + } + } + #endif /* KANJI */ nfPtr->fa = *faPtr; nfPtr->deletePending = 0; UpdateDependantFonts(fiPtr, tkwin, namedHashPtr); *************** *** 836,842 **** --- 1312,1322 ---- CachedFontKey key; Tcl_HashEntry *cacheHashPtr, *namedHashPtr; TkFont *fontPtr; + #ifdef KANJI + int new; + #else int new, descent; + #endif /* KANJI */ NamedFont *nfPtr; char *string; *************** *** 896,902 **** --- 1376,1398 ---- fontPtr->cacheHashPtr = cacheHashPtr; fontPtr->namedHashPtr = namedHashPtr; + #ifdef KANJI + switch(Tk_FontType(fontPtr)) { + case TK_FONT_COMPOUND: + case TK_FONT_GENERIC: { + wchar wTmp = '0'; + Tk_MeasureWChars((Tk_Font) fontPtr, &wTmp, 1, 0, 0, &fontPtr->tabWidth); + break; + } + case TK_FONT_2BYTES: { + wchar wTmp[] = { 0xa3b0, 0x0000 }; /* Zenkaku '0' (EUC) */ + Tk_MeasureWChars((Tk_Font) fontPtr, wTmp, 1, 0, 0, &fontPtr->tabWidth); + break; + } + } + #else Tk_MeasureChars((Tk_Font) fontPtr, "0", 1, 0, 0, &fontPtr->tabWidth); + #endif /* KANJI */ if (fontPtr->tabWidth == 0) { fontPtr->tabWidth = fontPtr->fm.maxWidth; } *************** *** 911,916 **** --- 1407,1417 ---- fontPtr->tabWidth = 1; } + #ifdef KANJI + /* + * These emulation should be done in platform specific font methods. + */ + #else /* * Get information used for drawing underlines in generic code on a * non-underlined font. *************** *** 935,940 **** --- 1436,1442 ---- fontPtr->underlineHeight = 1; } } + #endif /* KANJI */ return (Tk_Font) fontPtr; } *************** *** 1013,1018 **** --- 1515,1530 ---- nfPtr->refCount--; if ((nfPtr->refCount == 0) && (nfPtr->deletePending != 0)) { Tcl_DeleteHashEntry(fontPtr->namedHashPtr); + #ifdef KANJI + if (nfPtr->fa.fontType == TK_FONT_COMPOUND) { + if (nfPtr->fa.asciiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.asciiFaPtr); + } + if (nfPtr->fa.kanjiFaPtr != NULL) { + ckfree((char *)nfPtr->fa.kanjiFaPtr); + } + } + #endif /* KANJI */ ckfree((char *) nfPtr); } } *************** *** 1047,1052 **** --- 1559,1569 ---- TkFont *fontPtr; fontPtr = (TkFont *) tkfont; + #ifdef KANJI + if (Tk_FontType(fontPtr) == TK_FONT_COMPOUND) { + fontPtr = (TkFont *)fontPtr->asciiFontPtr; + } + #endif /* KANJI */ return fontPtr->fid; } *************** *** 1122,1127 **** --- 1639,1647 ---- { TkFont *fontPtr; char *family, *weightString, *slantString; + #ifdef KANJI + char *charset; + #endif /* KANJI */ char *src, *dest; int upper, len; *************** *** 1135,1140 **** --- 1655,1663 ---- */ family = fontPtr->fa.family; + #ifdef KANJI + charset = fontPtr->fa.charset; + #endif /* KANJI */ if (strncasecmp(family, "itc ", 4) == 0) { family = family + 4; } *************** *** 1153,1158 **** --- 1676,1716 ---- family = "ZapfChancery"; } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; + #ifdef KANJI + #ifdef __WIN32__ + } else if ((strcasecmp(family, "fixed") == 0 && strncasecmp(charset, "jisx0208", 8)) || + strcasecmp(charset, "shiftjis") == 0) { + unsigned char *gothics[] = { + "Gothic", + "\x83\x53\x83\x56\x83\x62\x83\x4e", + "\xba\xde\xbc\xaf\xb8", + }; + int i; + extern char *TkWinConvertToNativeString _ANSI_ARGS_((char *str)); + char *orgfamily = family; + char *nstr = TkWinConvertToNativeString(orgfamily); + family = NULL; + for (i = 0; i < sizeof(gothics)/sizeof(gothics[0]); i++) { + if (strstr(nstr, (char*)gothics[i])) { + family = "GothicBBB-Medium-EUC-H"; + break; + } + } + if (family == NULL) { + family = "Ryumin-Light-EUC-H"; + } + if (nstr != orgfamily) + ckfree(nstr); + #else /* __WIN32__ */ + } else if (strcasecmp(family, "fixed") == 0) { + if (strncasecmp(charset, "jisx0208", 8) == 0) { + /* Must be EUC encoding font. */ + family = "Ryumin-Light-EUC-H"; + } else { + family = "Courier"; + } + #endif /* __WIN32__ */ + #endif /* KANJI */ } else { /* * Inline, capitalize the first letter of each word, lowercase the *************** *** 2384,2389 **** --- 2942,2958 ---- faPtr->slant = TK_FS_ROMAN; faPtr->underline = 0; faPtr->overstrike = 0; + #ifdef KANJI + faPtr->setwidth = TK_SW_NORMAL; + faPtr->foundry = NULL; + faPtr->charset = NULL; + faPtr->fontType = TK_FONT_GENERIC; + faPtr->asciiFontName = NULL; + faPtr->kanjiFontName = NULL; + faPtr->asciiFaPtr = NULL; + faPtr->kanjiFaPtr = NULL; + faPtr->pointAdjust = 0.0; + #endif /* KANJI */ } /* *************** *** 2429,2434 **** --- 2998,3009 ---- return TCL_ERROR; } + #ifdef KANJI + if (faPtr->fontType == TK_FONT_COMPOUND) { + return ConfigCompoundAttributesObj(interp, tkwin, objc, objv, faPtr); + } + #endif /* KANJI */ + for (i = 0; i < objc; i += 2) { option = Tcl_GetStringFromObj(objv[i], NULL); value = objv[i + 1]; *************** *** 2438,2443 **** --- 3013,3025 ---- return TCL_ERROR; } switch (index) { + #ifdef KANJI + case FONT_FOUNDRY: + string = Tcl_GetStringFromObj(value, NULL); + faPtr->foundry = Tk_GetUid(string); + break; + + #endif /* KANJI */ case FONT_FAMILY: string = Tcl_GetStringFromObj(value, NULL); faPtr->family = Tk_GetUid(string); *************** *** 2481,2490 **** --- 3063,3205 ---- } faPtr->overstrike = n; break; + + #ifdef KANJI + case FONT_CHARSET: + string = Tcl_GetStringFromObj(value, NULL); + faPtr->charset = Tk_GetUid(string); + break; + + #endif /* KANJI */ } } return TCL_OK; } + #ifdef KANJI + + /* + *--------------------------------------------------------------------------- + * + * ConfigCompoundAttributesObj -- + * + * Process command line options to fill in fields of a properly + * initialized compound font and its descendant fonts attributes + * structure. + * + * Results: + * A standard Tcl return value. If TCL_ERROR is returned, an + * error message will be left in interp's result object. + * + * Side effects: + * The fields of the font attributes structure get filled in with + * information from argc/argv. If an error occurs while parsing, + * the font attributes structure will contain all modifications + * specified in the command line options up to the point of the + * error. + * + *--------------------------------------------------------------------------- + */ + + static int + ConfigCompoundAttributesObj(interp, tkwin, objc, objv, faPtr) + Tcl_Interp *interp; /* Interp for error return. */ + Tk_Window tkwin; /* For display on which font will be used. */ + int objc; /* Number of elements in argv. */ + Tcl_Obj *CONST objv[]; /* Command line options. */ + TkFontAttributes *faPtr; /* Font attributes structure whose fields + * are to be modified. Structure must already + * be properly initialized. */ + { + int i, n; + double d; + char *option; + Tcl_Obj *value; + TkFontAttributes *asciiFaPtr = faPtr->asciiFaPtr; + TkFontAttributes *kanjiFaPtr = faPtr->kanjiFaPtr; + int index; + int newSize = faPtr->pointsize; + double newAdjust = faPtr->pointAdjust; + double aP; + + if (faPtr->fontType != TK_FONT_COMPOUND) { + panic("ConfigCompoundAttributesObj() was called for non-compound fonts."); + } + + if (objc & 1) { + char *string = Tcl_GetStringFromObj(objv[objc - 1], NULL); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "missing value for \"", + string, "\" option", (char *) NULL); + return TCL_ERROR; + } + + for (i = 0; i < objc; i += 2) { + option = Tcl_GetStringFromObj(objv[i], NULL); + value = objv[i + 1]; + + if (Tcl_GetIndexFromObj(interp, objv[i], fontOpt, "option", 1, + &index) != TCL_OK) { + return TCL_ERROR; + } + switch (index) { + /* Ignore foundry, family, weight, slant, charset. */ + case FONT_SIZE: { + if (Tcl_GetIntFromObj(interp, value, &n) != TCL_OK) { + return TCL_ERROR; + } + newSize = n; + break; + } + + case FONT_UNDERLINE: { + if (Tcl_GetBooleanFromObj(interp, value, &n) != TCL_OK) { + return TCL_ERROR; + } + faPtr->underline = n; + #ifdef __WIN32__ + asciiFaPtr->underline = kanjiFaPtr->underline = n; + #endif + break; + } + + case FONT_OVERSTRIKE: { + if (Tcl_GetBooleanFromObj(interp, value, &n) != TCL_OK) { + return TCL_ERROR; + } + faPtr->overstrike = n; + #ifdef __WIN32__ + asciiFaPtr->overstrike = kanjiFaPtr->overstrike = n; + #endif + break; + } + + case FONT_POINTADJUST: { + if (Tcl_GetDoubleFromObj(interp, value, &d) != TCL_OK) { + return TCL_ERROR; + } + newAdjust = d; + break; + } + } + } + + if (newSize != faPtr->pointsize || newAdjust != faPtr->pointAdjust) { + if (newSize < 0) { + aP = -((double)(-newSize) * newAdjust); + } else { + aP = (double)(newSize) * newAdjust; + } + if (aP < 0) { + int tmp = (int)(-aP + 0.5); + asciiFaPtr->pointsize = -tmp; + } else { + asciiFaPtr->pointsize = (int)(aP + 0.5); + } + faPtr->pointAdjust = newAdjust; + faPtr->pointsize = kanjiFaPtr->pointsize = newSize; + } + return TCL_OK; + } + #endif /* KANJI */ /* *--------------------------------------------------------------------------- *************** *** 2523,2528 **** --- 3238,3248 ---- char *str; Tcl_Obj *newPtr; + #ifdef KANJI + char compoundName[1024]; + char pointAdjustBuf[32]; + #endif /* KANJI */ + start = 0; end = FONT_NUMFIELDS; if (objPtr != NULL) { *************** *** 2539,2544 **** --- 3259,3273 ---- num = 0; /* Needed only to prevent compiler * warning. */ switch (i) { + #ifdef KANJI + case FONT_FOUNDRY: + str = faPtr->foundry; + if (str == NULL) { + str = ""; + } + break; + + #endif /* KANJI */ case FONT_FAMILY: str = faPtr->family; if (str == NULL) { *************** *** 2548,2553 **** --- 3277,3288 ---- case FONT_SIZE: num = faPtr->pointsize; + #ifdef KANJI + if (num < 0) { + Tk_Window tkwin = Tk_MainWindow(interp); + num = TkpConvertPixelToPoint(tkwin, -num); + } + #endif /* KANJI */ break; case FONT_WEIGHT: *************** *** 2565,2570 **** --- 3300,3335 ---- case FONT_OVERSTRIKE: num = faPtr->overstrike; break; + + #ifdef KANJI + case FONT_CHARSET: + str = faPtr->charset; + if (str == NULL) { + str = ""; + } + break; + + case FONT_POINTADJUST: + if (faPtr->fontType == TK_FONT_COMPOUND) { + double pa = faPtr->pointAdjust; + sprintf(pointAdjustBuf, "%f", pa); + str = pointAdjustBuf; + } else { + str = NULL; + } + break; + + case FONT_COMPOUND: + if (faPtr->fontType == TK_FONT_COMPOUND) { + sprintf(compoundName, "{%s} {%s}", + faPtr->asciiFontName, faPtr->kanjiFontName); + str = compoundName; + } else { + str = ""; + } + break; + + #endif /* KANJI */ } if (objPtr == NULL) { Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(interp), *************** *** 2729,2734 **** --- 3494,3565 ---- return TCL_OK; } + #ifdef CHECK_XLFD + Tk_Uid + NormalizeXLFD(string) + Tk_Uid string; + { + /* + * Checking BOGUS XLFD. + * + * On XFree86 + X-TT(TrueType rasterizer enhancement for XFree86), + * returned value of XGetAtomName() for XGetFontProperty(XA_FONT) + * is NOT valid. + * + * On Solaris 2.x /usr/openwin/bin/X, the value is also NOT valid. + * + */ + int i = 0; + int oLen = 0; + char *str = string; + while (*str != '\0') { + if (*str == '-') i++; + str++; + oLen++; + } + if (oLen > 1024) { + /* + * Very bad. X protocol violation. It must be <= 255. + * Ignore such a entry. + */ + return string; + } + + if (i > XLFD_NUMFIELDS) { + CONST char *found = NULL; + char fixedXLFD[1025]; + + str = string; + if (str[oLen - 1] == '-') { + /* + * First, check Bogus name returned from /usr/openwin/bin/X + */ + oLen--; + memcpy((VOID *)fixedXLFD, (VOID *)string, (unsigned int)(oLen)); + fixedXLFD[oLen] = '\0'; + return Tk_GetUid(fixedXLFD); + } + + /* + * Convert the last "--" to "-". + */ + while ((str = strstr(str, "--")) != NULL) { + found = str; + str++; + } + if (found != NULL) { + int bLen = found - string; + memcpy((VOID *)fixedXLFD, (VOID *)string, (unsigned int)bLen); + memcpy((VOID *)(fixedXLFD + bLen), (VOID *)(string + bLen + 1), + (unsigned int)(oLen - bLen - 1)); + fixedXLFD[oLen] = '\0'; + return Tk_GetUid(fixedXLFD); + } + } + return string; + } + + #endif /* CHECK_XLFD */ /* *--------------------------------------------------------------------------- * *************** *** 2759,2767 **** int i, j; char *field[XLFD_NUMFIELDS + 2]; Tcl_DString ds; ! memset(field, '\0', sizeof(field)); str = string; if (*str == '-') { str++; --- 3590,3610 ---- int i, j; char *field[XLFD_NUMFIELDS + 2]; Tcl_DString ds; ! ! #ifdef CHECK_XLFD ! Tk_Uid fixedXLFD = NULL; ! Tk_Uid tmp = NULL; ! #endif /* CHECK_XLFD */ ! memset(field, '\0', sizeof(field)); + #ifdef CHECK_XLFD + tmp = Tk_GetUid(string); + fixedXLFD = NormalizeXLFD((char *)string); + if (fixedXLFD != tmp) { + string = fixedXLFD; + } + #endif /* CHECK_XLFD */ str = string; if (*str == '-') { str++; *************** *** 2817,2822 **** --- 3660,3668 ---- if (FieldSpecified(field[XLFD_FOUNDRY])) { xaPtr->foundry = Tk_GetUid(field[XLFD_FOUNDRY]); + #ifdef KANJI + xaPtr->fa.foundry = xaPtr->foundry; + #endif /* KANJI */ } if (FieldSpecified(field[XLFD_FAMILY])) { *************** *** 2838,2843 **** --- 3684,3692 ---- if (FieldSpecified(field[XLFD_SETWIDTH])) { xaPtr->setwidth = TkFindStateNum(NULL, NULL, xlfdSetwidthMap, field[XLFD_SETWIDTH]); + #ifdef KANJI + xaPtr->fa.setwidth = xaPtr->setwidth; + #endif /* KANJI */ } /* XLFD_ADD_STYLE ignored. */ *************** *** 2888,2900 **** --- 3737,3774 ---- &xaPtr->fa.pointsize) != TCL_OK) { return TCL_ERROR; } + #ifdef KANJI + /* Well, looks like specfying pixel size is stronger than + * specifying point size. I want to keep the size of the font + * as POINT SIZE. To notice that point size was overriden by + * pixel size, invert the sign. And, convert it to accurate + * point size when I can use Tk_Display(tkwin).*/ + xaPtr->fa.pointsize = -(xaPtr->fa.pointsize); + #endif /* KANJI */ + } + + #ifdef KANJI + #ifdef USE_FONT_RESOLUTION + if (FieldSpecified(field[XLFD_RESOLUTION_X])) { + if (Tcl_GetInt(NULL, field[XLFD_RESOLUTION_X], &(xaPtr->resX)) != TCL_OK) { + xaPtr->resX = 0; + } } + if (FieldSpecified(field[XLFD_RESOLUTION_Y])) { + if (Tcl_GetInt(NULL, field[XLFD_RESOLUTION_Y], &(xaPtr->resY)) != TCL_OK) { + xaPtr->resY = 0; + } + } + #endif /* USE_FONT_RESOLUTION */ + #else + xaPtr->fa.pointsize = -xaPtr->fa.pointsize; /* XLFD_RESOLUTION_X ignored. */ /* XLFD_RESOLUTION_Y ignored. */ + #endif /* KANJI */ /* XLFD_SPACING ignored. */ *************** *** 2903,2908 **** --- 3777,3801 ---- if (FieldSpecified(field[XLFD_REGISTRY])) { xaPtr->charset = TkFindStateNum(NULL, NULL, xlfdCharsetMap, field[XLFD_REGISTRY]); + #ifdef KANJI + xaPtr->fa.charset = Tk_GetUid(field[XLFD_REGISTRY]); + if (!strncasecmp(xaPtr->fa.charset, "jisx0208", 8)) { + xaPtr->fa.fontType = TK_FONT_2BYTES; + } else if (!strncasecmp(xaPtr->fa.charset, "gb2312", 6)) { + xaPtr->fa.fontType = TK_FONT_2BYTES; + } else if (!strncasecmp(xaPtr->fa.charset, "ksc5601", 7)) { + xaPtr->fa.fontType = TK_FONT_2BYTES; + } else if (!strncasecmp(xaPtr->fa.charset, "jisx0201", 8)) { + xaPtr->fa.fontType = TK_FONT_GENERIC; + } else if (!strncasecmp(xaPtr->fa.charset, "iso8859", 7)) { + xaPtr->fa.fontType = TK_FONT_GENERIC; + } else { + /* Need further check by platform specific method. To + * use this font, we must know whether the font is for + * 2 byte charset or not. */ + xaPtr->fa.fontType = TK_FONT_OTHER; + } + #endif /* KANJI */ } if (FieldSpecified(field[XLFD_ENCODING])) { xaPtr->encoding = atoi(field[XLFD_ENCODING]); *************** *** 3005,3008 **** --- 3898,4176 ---- return chunkPtr; } + #ifdef KANJI + + /* + *--------------------------------------------------------------------------- + * + * TkpDefaultFontPkgInit + * + * Initialize default font environment. + * + * Results: + * failsafe font environment is initialized. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + TkpDefaultFontPkgInit(tkwin) + Tk_Window tkwin; + { + static int defFontInited = 0; + int new = 0; + Tcl_HashEntry *ent = NULL; + + if (defFontInited == 0) { + if (defaultFontTab == NULL) { + defaultFontTab = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(defaultFontTab, TCL_ONE_WORD_KEYS); + } + if (displayInitTab == NULL) { + displayInitTab = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable)); + Tcl_InitHashTable(displayInitTab, TCL_ONE_WORD_KEYS); + } + defFontInited = 1; + } + + ent = Tcl_CreateHashEntry(displayInitTab, (char *)Tk_Display(tkwin), &new); + return new; + } + + /* + *--------------------------------------------------------------------------- + * + * TkpDefaultFontPkgFree + * + * Free default font environment. + * + * Results: + * failsafe font environment is freed. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + void + TkpDefaultFontPkgFree() + { + Tcl_HashEntry *ent; + Tcl_HashSearch search; + TkDefaultFont *dFontPtr; + ent = Tcl_FirstHashEntry(defaultFontTab, &search); + while (ent != NULL) { + dFontPtr = (TkDefaultFont *)Tcl_GetHashValue(ent); + if (dFontPtr != NULL) { + DeleteDefaultFont(dFontPtr); + } + ent = Tcl_NextHashEntry(&search); + } + Tcl_DeleteHashTable(defaultFontTab); + Tcl_DeleteHashTable(displayInitTab); + } + + /* + *--------------------------------------------------------------------------- + * + * AllocDefaultFont + * + * Allocate default font structure. + * + * Results: + * A TkDefaultFont structure will be allocated. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + static TkDefaultFont * + AllocDefaultFont(tkwin, name) + Tk_Window tkwin; + char *name; + { + TkDefaultFont *ret = (TkDefaultFont *)ckalloc(sizeof(TkDefaultFont)); + if (ret == NULL) { + return NULL; + } + ret->tkfont = (Tk_Font)TkpGetNativeFont(tkwin, name); + if (ret->tkfont == NULL) { + ckfree((char *)ret); + return NULL; + } + ret->fontName = Tk_GetUid(name); + return ret; + } + + /* + *--------------------------------------------------------------------------- + * + * DeleteDefaultFont + * + * Delete default font structure. + * + * Results: + * A TkDefaultFont structure allocated by AllocDefaultFont() + * will be Deleted. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + static void + DeleteDefaultFont(dFontPtr) + TkDefaultFont *dFontPtr; + { + TkpDeleteFont((TkFont *)(dFontPtr->tkfont)); + ckfree((char *)dFontPtr); + } + + + static void + TheDefaultFontHasChanged(clientData) + ClientData clientData; /* Display */ + { + Display *dpy = (Display *)clientData; + TkMainInfo *mainPtr; + + for (mainPtr = tkMainWindowList; mainPtr != NULL; + mainPtr = mainPtr->nextPtr) { + RecomputeWidgetsOnDisplay(mainPtr->winPtr, dpy); + } + } + + static void + RecomputeWidgetsOnDisplay(winPtr, dpy) + TkWindow *winPtr; + Display *dpy; + { + if (Tk_Display(winPtr) == dpy + && (winPtr->classProcsPtr != NULL) + && (winPtr->classProcsPtr->geometryProc != NULL)) { + (*winPtr->classProcsPtr->geometryProc)(winPtr->instanceData); + } + for (winPtr = winPtr->childList; winPtr != NULL; winPtr = winPtr->nextPtr) { + RecomputeWidgetsOnDisplay(winPtr, dpy); + } + } + + /* + *--------------------------------------------------------------------------- + * + * SetDefaultFont + * + * Set a default font for a display. + * + * Results: + * Default font name is set to static area. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + static int + SetDefaultFont(interp, tkwin, name) + Tcl_Interp *interp; + Tk_Window tkwin; + char *name; + { + TkDefaultFont *dFontPtr = NULL; + Tcl_HashEntry *ent = NULL; + int new = 0; + + if (name == NULL || name[0] == 0) { + ent = Tcl_FindHashEntry(defaultFontTab, (char *)Tk_Display(tkwin)); + if (ent != NULL) { + dFontPtr = (TkDefaultFont *)Tcl_GetHashValue(ent); + DeleteDefaultFont(dFontPtr); + Tcl_DeleteHashEntry(ent); + } + return TCL_OK; + } + + dFontPtr = AllocDefaultFont(tkwin, name); + if (dFontPtr == NULL) { + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "can't load font \"", name, "\".", NULL); + return TCL_ERROR; + } + + ent = Tcl_CreateHashEntry(defaultFontTab, (char *)Tk_Display(tkwin), &new); + if (ent != NULL && new != 1) { + TkDefaultFont *oldFontPtr = (TkDefaultFont *)Tcl_GetHashValue(ent); + DeleteDefaultFont(oldFontPtr); + } + Tcl_SetHashValue(ent, (ClientData)dFontPtr); + + Tcl_DoWhenIdle(TheDefaultFontHasChanged, (ClientData) Tk_Display(tkwin)); + + return TCL_OK; + } + + /* + *--------------------------------------------------------------------------- + * + * GetDefaultFontName + * + * Get the default font name for the display. + * + * Results: + * Return the default font name set by Tk_SetDefaultFont(). + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + static char * + GetDefaultFontName(tkwin) + Tk_Window tkwin; + { + Tcl_HashEntry *ent = Tcl_FindHashEntry(defaultFontTab, (char *)Tk_Display(tkwin)); + if (ent != NULL) { + TkDefaultFont *dFontPtr = (TkDefaultFont *)Tcl_GetHashValue(ent); + return dFontPtr->fontName; + } else { + return NULL; + } + } + + /* + *--------------------------------------------------------------------------- + * + * TkpGetDefaultFontByDisplay + * + * Get the failsafe font. + * + * Results: + * A Tk_Font created by AllocDefaultFont() is returned. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + Tk_Font + TkpGetDefaultFontByDisplay(dpy) + Display *dpy; + { + Tcl_HashEntry *ent = Tcl_FindHashEntry(defaultFontTab, (char *)dpy); + if (ent != NULL) { + TkDefaultFont *dFontPtr = (TkDefaultFont *)Tcl_GetHashValue(ent); + return dFontPtr->tkfont; + } + return NULL; + } + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkFont.h ./generic/tkFont.h *** ../../tk8.0.5/generic/tkFont.h Tue Sep 15 03:23:10 1998 --- ./generic/tkFont.h Tue Apr 6 20:04:01 1999 *************** *** 35,40 **** --- 35,70 ---- int slant; /* Slant flag; see below for def'n. */ int underline; /* Non-zero for underline font. */ int overstrike; /* Non-zero for overstrike font. */ + #ifdef KANJI + int setwidth; /* setwidth field. */ + Tk_Uid foundry; /* font foundry field. */ + Tk_Uid charset; /* font charset field. */ + int fontType; /* One of the follows: + * TK_FONT_GENERIC + * TK_FONT_2BYTES + * TK_FONT_OTHER + * TK_FONT_COMPOUND */ + /* + * This macro only can be used in file that include this header. + * Otherwise, use convinient functions. + */ + #define Tk_FontType(tkfont) (((TkFont *)tkfont)->fa.fontType) + #define Tk_FontSize(tkfont) (((TkFont *)tkfont)->fa.pointsize) + #define Tk_FontFamily(tkfont) (((TkFont *)tkfont)->fa.family) + #define Tk_FontCharset(tkfont) (((TkFont *)tkfont)->fa.charset) + #define Tk_FontFoundry(tkfont) (((TkFont *)tkfont)->fa.foundry) + Tk_Uid asciiFontName; + Tk_Uid kanjiFontName; /* if fontType == TK_FONT_COMPOUND, + * use these names. */ + struct TkFontAttributes *asciiFaPtr; + struct TkFontAttributes *kanjiFaPtr; + /* if fontType == TK_FONT_COMPOUND, + * use these attributes. malloc'd. */ + double pointAdjust; /* Point size adjustment between kanji + * font and ascii font. + * (ascii size) / (kanji size). */ + #define Tk_FontPointAdjust(tkfont) (((TkFont *)tkfont)->fa.pointAdjust) + #endif /* KANJI */ } TkFontAttributes; /* *************** *** 121,126 **** --- 151,161 ---- * that was used to create this font. */ TkFontMetrics fm; /* Font metrics determined when font was * created. */ + #ifdef KANJI + struct TkFont *asciiFontPtr; + struct TkFont *kanjiFontPtr;/* if fa.fontType == TK_FONT_COMPOUND, + * use these pointer. */ + #endif /* KANJI */ } TkFont; /* *************** *** 140,145 **** --- 175,187 ---- * family), see below for definition. */ int encoding; /* Variations within a charset for the * glyphs above character 127. */ + #ifdef KANJI + #ifdef USE_FONT_RESOLUTION + int resX; + int resY; /* Care X server's resolution for more + * precise font selection. */ + #endif /* USE_FONT_RESOLUTION */ + #endif /* KANJI */ } TkXLFDAttributes; /* *************** *** 162,167 **** --- 204,212 ---- #define TK_CS_NORMAL 0 #define TK_CS_SYMBOL 1 #define TK_CS_OTHER 2 + #ifdef KANJI + #define TK_CS_KANJI 3 + #endif /* KANJI */ /* * The following defines specify the meaning of the fields in a fully *************** *** 205,214 **** --- 250,279 ---- EXTERN TkFont * TkpGetFontFromAttributes _ANSI_ARGS_(( TkFont *tkFontPtr, Tk_Window tkwin, CONST TkFontAttributes *faPtr)); + #ifdef KANJI + EXTERN void TkpUpdateCompoundFont _ANSI_ARGS_((TkFont *tkFontPtr, + CONST TkFontAttributes *faPtr)); + #endif /* KANJI */ EXTERN void TkpGetFontFamilies _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin)); EXTERN TkFont * TkpGetNativeFont _ANSI_ARGS_((Tk_Window tkwin, CONST char *name)); + + #ifdef KANJI + #ifndef __WIN32__ + EXTERN XFontStruct * TkpGetFontStruct _ANSI_ARGS_((Tk_Font tkfont)); + EXTERN XFontStruct * TkpGetAsciiFontStruct _ANSI_ARGS_((Tk_Font tkfont)); + EXTERN XFontStruct * TkpGetKanjiFontStruct _ANSI_ARGS_((Tk_Font tkfont)); + + EXTERN Tk_Uid TkpGetFontPropertyName _ANSI_ARGS_((Tk_Window tkwin, XFontStruct *fontPtr)); + EXTERN Tk_Uid TkpGetFontPropertyNameFromTkFont _ANSI_ARGS_((Tk_Window tkwin, Tk_Font tkfont)); + EXTERN Tk_Uid TkpFindFontnameFromFontStruct _ANSI_ARGS_((Tk_Window tkwin, XFontStruct *fontPtr)); + #endif /* __WIN32__ */ + #endif /* KANJI */ + + #ifdef CHECK_XLFD + EXTERN Tk_Uid NormalizeXLFD _ANSI_ARGS_((Tk_Uid string)); + #endif /* CHECK_XLFD */ # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLIMPORT diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkInt.h ./generic/tkInt.h *** ../../tk8.0.5/generic/tkInt.h Thu Oct 1 04:01:20 1998 --- ./generic/tkInt.h Mon May 10 19:10:17 1999 *************** *** 175,180 **** --- 175,183 ---- Atom timestampAtom; /* Atom for TIMESTAMP. */ Atom textAtom; /* Atom for TEXT. */ Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ + #ifdef KANJI + Atom cStringAtom; /* Atom for C_STRING. */ + #endif /* KANJI */ Atom applicationAtom; /* Atom for TK_APPLICATION. */ Atom windowAtom; /* Atom for TK_WINDOW. */ Atom clipboardAtom; /* Atom for CLIPBOARD. */ *************** *** 336,341 **** --- 339,357 ---- * the display when we no longer have any * Tk applications using it. */ + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + XIMStyles *imSupportedStyle; + unsigned long imIcValues; /* Or'd value of IC attributes supported by + this IM. */ + char *modifiers; /* Hint for specific support of the input + * method. Malloc'd. */ + XIC lastFocusedIC; /* IC that currently focused. */ + #ifdef XNDestroyCallback + XIMCallback destroyCallback; + #endif /* XNDestroyCallback */ + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ } TkDisplay; /* *************** *** 624,629 **** --- 640,650 ---- */ struct TkWindowPrivate *privatePtr; + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + TkpICAttribute *icAttr; /* Input context attributes. */ + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ } TkWindow; /* *************** *** 856,861 **** --- 877,889 ---- #ifndef TkpDefineNativeBitmaps EXTERN void TkpDefineNativeBitmaps _ANSI_ARGS_((void)); #endif + #ifdef KANJI + EXTERN int TkpDefaultFontPkgInit _ANSI_ARGS_((Tk_Window tkwin)); + EXTERN void TkpDefaultFontPkgFree _ANSI_ARGS_((void)); + #ifndef __WIN32__ + EXTERN void TkpFontCachePkgInit _ANSI_ARGS_((void)); + #endif /* __WIN32__ */ + #endif /* KANJI */ EXTERN void TkpDisplayWarning _ANSI_ARGS_((char *msg, char *title)); EXTERN void TkpGetAppName _ANSI_ARGS_((Tcl_Interp *interp, *************** *** 981,986 **** --- 1009,1035 ---- */ EXTERN int TkUnsupported1Cmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); + + #ifdef KANJI + EXTERN int TkpConvertPointToPixel _ANSI_ARGS_((Tk_Window tkwin, int pointsize)); + EXTERN int TkpConvertPixelToPoint _ANSI_ARGS_((Tk_Window tkwin, int pixelsize)); + EXTERN int TkpGetDPI _ANSI_ARGS_((Tk_Window tkwin, double *realDPIRet)); + EXTERN Tk_Font TkpGetDefaultFontByDisplay _ANSI_ARGS_((Display *)); + EXTERN void TkpGetFailsafeFont _ANSI_ARGS_((Tk_Font tkfont, + Tk_Font *asciiFont, Tk_Font *kanjiFont)); + EXTERN int TkpIsBreakablePoint _ANSI_ARGS_((wchar prev, wchar cur)); + EXTERN void TkpKinsokuPkgInit _ANSI_ARGS_((void)); + #endif /* KANJI */ + + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + EXTERN TkpICAttribute * TkpAllocICAttribute _ANSI_ARGS_((Tk_Window tkwin)); + EXTERN void TkpDeleteICAttribute _ANSI_ARGS_((Tk_Window tkwin, TkpICAttribute *attr)); + EXTERN void TkpCreateIMGenericHandler _ANSI_ARGS_ ((Tk_Window tkwin)); + EXTERN void TkpDeleteIMGenericHandler _ANSI_ARGS_ ((Tk_Window tkwin)); + EXTERN unsigned long TkpGetSupportedICAttribute _ANSI_ARGS_ ((XIMValuesList *icVal)); + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLIMPORT diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkKinsoku.c ./generic/tkKinsoku.c *** ../../tk8.0.5/generic/tkKinsoku.c Thu Jan 1 09:00:00 1970 --- ./generic/tkKinsoku.c Mon May 10 19:10:17 1999 *************** *** 0 **** --- 1,357 ---- + /* + * tkKinsoku.c -- + * + * This file contains modules to implement "kinsoku" (avoiding + * placing taboo character at the begin/end of line) management + * for text drawing. + * + * Author: m-hirano@sra.co.jp + * + * Copyright 1999 Software Research Associates, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + */ + + #ifndef lint + static char rcsid[] = "$Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/generic/tkKinsoku.c,v 1.5 1999/04/23 07:50:10 m-hirano Exp $"; + #endif /* !lint */ + + #include "tkPort.h" + #include "tkInt.h" + + #define KANJI_RANGE 65536 + + #define WRAPUP 1 /* taboo at the begin of line. */ + #define WRAPDOWN 2 /* taboo at the end of line. */ + #define WRAPMASK 3 + + static char kinsokuTable[KANJI_RANGE]; + + #define SetWrapup(wc) kinsokuTable[(wc)] |= WRAPUP + #define SetWrapdown(wc) kinsokuTable[(wc)] |= WRAPDOWN + #define SetBoth(wc) kinsokuTable[(wc)] |= (WRAPUP|WRAPDOWN) + + #define ClearWrapup(wc) kinsokuTable[(wc)] &= ~WRAPUP + #define ClearWrapdown(wc) kinsokuTable[(wc)] &= ~WRAPDOWN + #define ClearBoth(wc) kinsokuTable[(wc)] = 0 + + + static int kinsokuInitialized = 0; + + static int kinsokuEnable = 1; + + + static void DoKinsokuRecurrsive _ANSI_ARGS_((TkWindow *winPtr)); + static void TheKinsokuTableHasChanged _ANSI_ARGS_((ClientData clientData)); + + void + TkpKinsokuPkgInit() + { + if (kinsokuInitialized == 0) { + (VOID)memset((VOID *)kinsokuTable, 0, KANJI_RANGE); + kinsokuInitialized = 1; + } + } + + + static void + DoKinsokuRecurrsive(winPtr) + TkWindow *winPtr; + { + if (winPtr->classProcsPtr != NULL && + winPtr->classProcsPtr->geometryProc != NULL) { + (winPtr->classProcsPtr->geometryProc)(winPtr->instanceData); + } + for (winPtr = winPtr->childList; winPtr != NULL; + winPtr = winPtr->nextPtr) { + DoKinsokuRecurrsive(winPtr); + } + } + + + static void + TheKinsokuTableHasChanged(clientData) + ClientData clientData; + { + TkMainInfo *mainPtr; + + for (mainPtr = tkMainWindowList; mainPtr != NULL; + mainPtr = mainPtr->nextPtr) { + DoKinsokuRecurrsive(mainPtr->winPtr); + } + } + + + + /* + *--------------------------------------------------------------------------- + * + * TkpIsBreakablePoint -- + * + * Examin where we can break the line. + * + * Results: + * If the point between 'cur' and 'next' is breakable, return + * 1. otherwise return 0. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + TkpIsBreakablePoint(cur, next) + wchar cur; + wchar next; + { + if (kinsokuEnable == 1) { + if (isascii(cur) && isascii(next)) { + return isspace(cur); + } else { + if (next == 0 || cur == 0) { + return 0; + } else { + return ( ((kinsokuTable[cur] & WRAPDOWN) != WRAPDOWN) && + ((kinsokuTable[next] & WRAPUP) != WRAPUP) ); + } + } + } else { + return ISWSPACE(cur); + } + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_KinsokuObjCmd -- + * + * Manage "kinsoku" table. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * contents of kinsokuTable might be changed. + * + *---------------------------------------------------------------------- + */ + + int + Tk_KinsokuObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window associated with interpreter. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ + { + static char *optionStrings[] = { + "add", + "clear", + "delete", + "disable", + "enable", + "show", + NULL + }; + enum options { + KINSOKU_ADD, + KINSOKU_CLEAR, + KINSOKU_DELETE, + KINSOKU_DISABLE, + KINSOKU_ENABLE, + KINSOKU_SHOW + }; + int index; + + static char *tblStrings[] = { + "begin", + "end", + "both", + NULL + }; + enum tbl { + TBL_BEGIN, + TBL_END, + TBL_BOTH + }; + int tblIdx; + + if (kinsokuInitialized == 0) { + TkpKinsokuPkgInit(); + } + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "command ?begin|end|both? ?arg?"); + return TCL_ERROR; + } + + if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, + "option", 0, &index) != TCL_OK) { + return TCL_ERROR; + } + + if ((enum options)index != KINSOKU_ENABLE && + (enum options)index != KINSOKU_DISABLE) { + if (Tcl_GetIndexFromObj(interp, objv[2], tblStrings, + "table", 0, &tblIdx) != TCL_OK) { + return TCL_ERROR; + } + } + + switch ((enum options)index) { + case KINSOKU_ENABLE: { + if (kinsokuEnable == 0) { + kinsokuEnable = 1; + goto updateKinsoku; + } else { + return TCL_OK; + } + break; + } + + case KINSOKU_DISABLE: { + if (kinsokuEnable == 1) { + kinsokuEnable = 0; + goto updateKinsoku; + } else { + return TCL_OK; + } + break; + } + + case KINSOKU_ADD: + case KINSOKU_DELETE: { + char *str; + wchar *wBuf; + int wLen; + int i; + int kanjiCode = TCL_ANY; + + for (i = 3; i < objc; i++) { + str = Tcl_GetStringFromObj(objv[i], NULL); + if (str == NULL) continue; + (void)Tcl_KanjiString(interp, str, NULL, &kanjiCode); + wLen = Tcl_KanjiEncode(kanjiCode, str, NULL); + wBuf = (wchar *)ckalloc(sizeof(wchar) * (wLen + 1)); + (void)Tcl_KanjiEncode(kanjiCode, str, wBuf); + + switch((enum tbl)tblIdx) { + case TBL_BEGIN: { + if ((enum options)index == KINSOKU_ADD) { + SetWrapup(*wBuf); + } else { + ClearWrapup(*wBuf); + } + break; + } + case TBL_END: { + if ((enum options)index == KINSOKU_ADD) { + SetWrapdown(*wBuf); + } else { + ClearWrapdown(*wBuf); + } + break; + } + case TBL_BOTH: { + if ((enum options)index == KINSOKU_ADD) { + SetBoth(*wBuf); + } else { + ClearBoth(*wBuf); + } + break; + } + } + (void)ckfree((char *)wBuf); + } + + goto updateKinsoku; + break; + } + + case KINSOKU_CLEAR: { + switch((enum tbl)tblIdx) { + case TBL_BEGIN: { + int i; + for (i = 0; i < KANJI_RANGE; i++) { + ClearWrapup(i); + } + break; + } + case TBL_END: { + int i; + for (i = 0; i < KANJI_RANGE; i++) { + ClearWrapdown(i); + } + break; + } + case TBL_BOTH: { + (VOID)memset((VOID *)kinsokuTable, 0, KANJI_RANGE); + break; + } + } + + goto updateKinsoku; + break; + } + + case KINSOKU_SHOW: { + int kanjiCode = Tcl_KanjiCode(interp); + int i; + char *str; + int len; + wchar wTmp[2]; + int found; + + for (i = 0; i < KANJI_RANGE; i++) { + found = 0; + switch((enum tbl)tblIdx) { + case TBL_BEGIN: { + if (kinsokuTable[i] & WRAPUP) { + found = 1; + } + break; + } + case TBL_END: { + if (kinsokuTable[i] & WRAPDOWN) { + found = 1; + } + break; + } + case TBL_BOTH: { + if (kinsokuTable[i] == (WRAPUP|WRAPDOWN)) { + found = 1; + } + break; + } + } + if (found == 1) { + wTmp[0] = (wchar)i; + wTmp[1] = 0; + len = Tcl_KanjiDecode(kanjiCode, wTmp, NULL); + str = (char *)ckalloc(sizeof(char) * (len + 1)); + (void)Tcl_KanjiDecode(kanjiCode, wTmp, str); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), str, " ", NULL); + (void)ckfree((char *)str); + } + } + + return TCL_OK; + break; + } + + } + + updateKinsoku: + Tcl_DoWhenIdle(TheKinsokuTableHasChanged, (ClientData)NULL); + + return TCL_OK; + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkListbox.c ./generic/tkListbox.c *** ../../tk8.0.5/generic/tkListbox.c Tue Sep 15 03:23:13 1998 --- ./generic/tkListbox.c Fri Mar 12 00:36:58 1999 *************** *** 11,19 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkListbox.c,v 1.2 1998/09/14 18:23:13 stanton Exp $ */ #include "tkPort.h" #include "default.h" #include "tkInt.h" --- 11,23 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkListbox.c,v 1.9 1999/03/11 15:36:58 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif + #include "tkPort.h" #include "default.h" #include "tkInt.h" *************** *** 33,48 **** * it isn't. */ struct Element *nextPtr; /* Next in list of all elements of this * listbox, or NULL for last element. */ char text[4]; /* Characters of this element, NULL- * terminated. The actual space allocated * here will be as large as needed (> 4, * most likely). Must be the last field * of the record. */ } Element; #define ElementSize(stringLength) \ ((unsigned) (sizeof(Element) - 3 + stringLength)) ! /* * A data structure of the following type is kept for each listbox * widget managed by this file: --- 37,61 ---- * it isn't. */ struct Element *nextPtr; /* Next in list of all elements of this * listbox, or NULL for last element. */ + #ifdef TK_KANJI_OK + wchar *text; /* Characters of this element, NULL- + * terminated. The actual space allocated + * here will be as large as needed (> 4, + * most likely). Must be the last field + * of the record. */ + #else char text[4]; /* Characters of this element, NULL- * terminated. The actual space allocated * here will be as large as needed (> 4, * most likely). Must be the last field * of the record. */ + #endif /* TK_KANJI_OK */ } Element; + #ifndef TK_KANJI_OK #define ElementSize(stringLength) \ ((unsigned) (sizeof(Element) - 3 + stringLength)) ! #endif /* !TK_KANJI_OK */ /* * A data structure of the following type is kept for each listbox * widget managed by this file: *************** *** 292,297 **** --- 305,315 ---- static int ListboxFetchSelection _ANSI_ARGS_(( ClientData clientData, int offset, char *buffer, int maxBytes)); + #ifdef TK_KANJI_OK + static int ListboxFetchSelectionCtext _ANSI_ARGS_(( + ClientData clientData, int offset, char *buffer, + int maxBytes)); + #endif /* TK_KANJI_OK */ static void ListboxLostSelection _ANSI_ARGS_(( ClientData clientData)); static void ListboxRedrawRange _ANSI_ARGS_((Listbox *listPtr, *************** *** 424,429 **** --- 442,459 ---- ListboxEventProc, (ClientData) listPtr); Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING, ListboxFetchSelection, (ClientData) listPtr, XA_STRING); + #ifdef TK_KANJI_OK + Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(listPtr->tkwin, textAtom), + ListboxFetchSelectionCtext, + (ClientData) listPtr, + Tk_UsefulAtom(listPtr->tkwin, compoundTextAtom)); + Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(listPtr->tkwin, textAtom), + ListboxFetchSelectionCtext, + (ClientData) listPtr, + Tk_UsefulAtom(listPtr->tkwin, compoundTextAtom)); + #endif /* TK_KANJI_OK */ if (ConfigureListbox(interp, listPtr, argc-2, argv+2, 0) != TCL_OK) { goto error; } *************** *** 616,625 **** if (first >= listPtr->numElements) { goto done; } if (last >= listPtr->numElements) { last = listPtr->numElements-1; } ! for (elPtr = listPtr->firstPtr, i = 0; i < first; i++, elPtr = elPtr->nextPtr) { /* Empty loop body. */ --- 646,660 ---- if (first >= listPtr->numElements) { goto done; } + #ifdef BUGFIX + if ((argc == 4) && (last >= listPtr->numElements)) { + last = listPtr->numElements-1; + } + #else if (last >= listPtr->numElements) { last = listPtr->numElements-1; } ! #endif /* BUGFIX */ for (elPtr = listPtr->firstPtr, i = 0; i < first; i++, elPtr = elPtr->nextPtr) { /* Empty loop body. */ *************** *** 627,637 **** --- 662,681 ---- if (elPtr != NULL) { if (argc == 3) { if (first >= 0) { + #ifdef TK_KANJI_OK + interp->result = Tcl_DecodeWStr(interp, elPtr->text, NULL); + #else interp->result = elPtr->text; + #endif /* TK_KANJI_OK */ } } else { for ( ; i <= last; i++, elPtr = elPtr->nextPtr) { + #ifdef TK_KANJI_OK + Tcl_AppendElement(interp, Tcl_DecodeWStr(interp, + elPtr->text, NULL)); + #else Tcl_AppendElement(interp, elPtr->text); + #endif /* TK_KANJI_OK */ } } } *************** *** 955,960 **** --- 999,1007 ---- for (elPtr = listPtr->firstPtr; elPtr != NULL; ) { nextPtr = elPtr->nextPtr; + #ifdef TK_KANJI_OK + Tcl_FreeWStr(elPtr->text); + #endif /* TK_KANJI_OK */ ckfree((char *) elPtr); elPtr = nextPtr; } *************** *** 1309,1315 **** --- 1356,1367 ---- Tk_FontMetrics fm; if (fontChanged || maxIsStale) { + #ifdef TK_KANJI_OK + wchar wTmp = '0'; + listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, &wTmp, 1); + #else listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1); + #endif /* TK_KANJI_OK */ if (listPtr->xScrollUnit == 0) { listPtr->xScrollUnit = 1; } *************** *** 1385,1392 **** char **argv; /* New elements (one per entry). */ { register Element *prevPtr, *newPtr; int length, i, oldMaxWidth; ! /* * Find the element before which the new ones will be inserted. */ --- 1437,1447 ---- char **argv; /* New elements (one per entry). */ { register Element *prevPtr, *newPtr; + #ifdef TK_KANJI_OK + int i, oldMaxWidth; + #else int length, i, oldMaxWidth; ! #endif /* TK_KANJI_OK */ /* * Find the element before which the new ones will be inserted. */ *************** *** 1414,1423 **** --- 1469,1484 ---- oldMaxWidth = listPtr->maxWidth; for (i = argc ; i > 0; i--, argv++, prevPtr = newPtr) { + #ifdef TK_KANJI_OK + newPtr = (Element *)ckalloc((unsigned)sizeof(Element)); + newPtr->text = Tcl_GetWStr(NULL, *argv, NULL); + newPtr->textLength = Tcl_WStrlen(newPtr->text); + #else length = strlen(*argv); newPtr = (Element *) ckalloc(ElementSize(length)); newPtr->textLength = length; strcpy(newPtr->text, *argv); + #endif /* TK_KANJI_OK */ newPtr->pixelWidth = Tk_TextWidth(listPtr->tkfont, newPtr->text, newPtr->textLength); newPtr->lBearing = 0; *************** *** 1544,1549 **** --- 1605,1613 ---- if (elPtr->selected) { listPtr->numSelected -= 1; } + #ifdef TK_KANJI_OK + Tcl_FreeWStr(elPtr->text); + #endif /* TK_KANJI_OK */ ckfree((char *) elPtr); } listPtr->numElements -= count; *************** *** 2113,2119 **** --- 2177,2189 ---- if (needNewline) { Tcl_DStringAppend(&selection, "\n", 1); } + #ifdef TK_KANJI_OK + Tcl_DStringAppend(&selection, + Tcl_DecodeWStr(listPtr->interp, elPtr->text, NULL), + elPtr->textLength); + #else Tcl_DStringAppend(&selection, elPtr->text, elPtr->textLength); + #endif /* TK_KANJI_OK */ needNewline = 1; } } *************** *** 2142,2147 **** --- 2212,2300 ---- Tcl_DStringFree(&selection); return count; } + #ifdef TK_KANJI_OK + + /* + *---------------------------------------------------------------------- + * + * ListboxFetchSelectionCtext -- + * + * This procedure is similar to ListboxFetchSelection except + * it converts the selection to COMPOUND_TEXT before + * passing it to the requester. + * + * Results: + * See ListboxFetchSelection. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + static int + ListboxFetchSelectionCtext(clientData, offset, buffer, maxBytes) + ClientData clientData; /* Information about listbox widget. */ + int offset; /* Offset within selection of first + * byte to be returned. */ + char *buffer; /* Location in which to place + * selection. */ + int maxBytes; /* Maximum number of bytes to place + * at buffer, not including terminating + * NULL character. */ + { + register Listbox *listPtr = (Listbox *) clientData; + register Element *elPtr; + Tcl_DString selection; + int length, count, needNewline; + char *ctext; + + if (!listPtr->exportSelection) { + return -1; + } + + /* + * Use a dynamic string to accumulate the contents of the selection. + */ + + needNewline = 0; + Tcl_DStringInit(&selection); + for (elPtr = listPtr->firstPtr; elPtr != NULL; elPtr = elPtr->nextPtr) { + if (elPtr->selected) { + if (needNewline) { + Tcl_DStringAppend(&selection, "\n", 1); + } + ctext = Tk_WStrToCtext(elPtr->text, -1); + Tcl_DStringAppend(&selection, ctext, (int)strlen(ctext)); + ckfree(ctext); + needNewline = 1; + } + } + + length = Tcl_DStringLength(&selection); + if (length == 0) { + return -1; + } + + /* + * Copy the requested portion of the selection to the buffer. + */ + + count = length - offset; + if (count <= 0) { + count = 0; + } else { + if (count > maxBytes) { + count = maxBytes; + } + memcpy((VOID *) buffer, + (VOID *) (Tcl_DStringValue(&selection) + offset), (unsigned int)count); + } + buffer[count] = '\0'; + Tcl_DStringFree(&selection); + return count; + } + #endif /* KANJI */ /* *---------------------------------------------------------------------- diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkMenu.c ./generic/tkMenu.c *** ../../tk8.0.5/generic/tkMenu.c Tue Sep 15 03:23:14 1998 --- ./generic/tkMenu.c Fri Mar 12 00:37:00 1999 *************** *** 90,99 **** --- 90,106 ---- DEF_MENU_ENTRY_ACTIVE_FG, Tk_Offset(TkMenuEntry, activeFg), COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK |TK_CONFIG_NULL_OK}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-accelerator", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_ACCELERATOR, Tk_Offset(TkMenuEntry, accel), + COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK + |TK_CONFIG_NULL_OK}, + #else {TK_CONFIG_STRING, "-accelerator", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_ACCELERATOR, Tk_Offset(TkMenuEntry, accel), COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK |TK_CONFIG_NULL_OK}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_BORDER, "-background", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_BG, Tk_Offset(TkMenuEntry, border), COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK *************** *** 128,136 **** --- 135,149 ---- {TK_CONFIG_BOOLEAN, "-indicatoron", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_INDICATOR, Tk_Offset(TkMenuEntry, indicatorOn), CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|TK_CONFIG_DONT_SET_DEFAULT}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-label", (char *) NULL, (char *) NULL, + DEF_MENU_ENTRY_LABEL, Tk_Offset(TkMenuEntry, label), + COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK}, + #else {TK_CONFIG_STRING, "-label", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_LABEL, Tk_Offset(TkMenuEntry, label), COMMAND_MASK|CHECK_BUTTON_MASK|RADIO_BUTTON_MASK|CASCADE_MASK}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_STRING, "-menu", (char *) NULL, (char *) NULL, DEF_MENU_ENTRY_MENU, Tk_Offset(TkMenuEntry, name), CASCADE_MASK|TK_CONFIG_NULL_OK}, *************** *** 1450,1461 **** --- 1463,1482 ---- if (mePtr->label == NULL) { mePtr->labelLength = 0; } else { + #ifdef TK_KANJI_OK + mePtr->labelLength = Tcl_WStrlen(mePtr->label); + #else mePtr->labelLength = strlen(mePtr->label); + #endif /* TK_KANJI_OK */ } if (mePtr->accel == NULL) { mePtr->accelLength = 0; } else { + #ifdef TK_KANJI_OK + mePtr->accelLength = Tcl_WStrlen(mePtr->accel); + #else mePtr->accelLength = strlen(mePtr->accel); + #endif /* TK_KANJI_OK */ } /* *************** *** 1536,1549 **** --- 1557,1584 ---- char *value; if (mePtr->name == NULL) { + #ifdef TK_KANJI_OK + mePtr->name = + (char *) ckalloc((unsigned)(mePtr->labelLength * sizeof(wchar) + 1)); + strcpy(mePtr->name, (mePtr->label == NULL) ? "" : + Tcl_DecodeWStr(mePtr->menuPtr->interp, mePtr->label, NULL)); + #else mePtr->name = (char *) ckalloc((unsigned) (mePtr->labelLength + 1)); strcpy(mePtr->name, (mePtr->label == NULL) ? "" : mePtr->label); + #endif /* TK_KANJI_OK */ } if (mePtr->onValue == NULL) { + #ifdef TK_KANJI_OK + mePtr->onValue = + (char *) ckalloc((unsigned)(mePtr->labelLength * sizeof(wchar) + 1)); + strcpy(mePtr->onValue, (mePtr->label == NULL) ? "" : + Tcl_DecodeWStr(mePtr->menuPtr->interp, mePtr->label, NULL)); + #else mePtr->onValue = (char *) ckalloc((unsigned) (mePtr->labelLength + 1)); strcpy(mePtr->onValue, (mePtr->label == NULL) ? "" : mePtr->label); + #endif /* TK_KANJI_OK */ } /* *************** *** 1788,1799 **** --- 1823,1844 ---- for (i = 0; i < menuPtr->numEntries; i++) { char *label; + #ifdef TK_KANJI_OK + if (menuPtr->entries[i]->label != NULL ) { + label = Tcl_DecodeWStr(menuPtr->interp, menuPtr->entries[i]->label, NULL); + if (Tcl_StringMatch(label, string)) { + *indexPtr = i; + return TCL_OK; + } + } + #else label = menuPtr->entries[i]->label; if ((label != NULL) && (Tcl_StringMatch(menuPtr->entries[i]->label, string))) { *indexPtr = i; return TCL_OK; } + #endif /* TK_KANJI_OK */ } Tcl_AppendResult(interp, "bad menu entry index \"", *************** *** 2604,2615 **** --- 2649,2678 ---- Tcl_DStringInit(&childDString); Tcl_DStringAppend(&childDString, Tk_PathName(menuPtr->tkwin), -1); + #ifdef TK_KANJI_OK + { + char *dEnd; + destString = Tcl_DStringValue(&childDString); + dEnd = destString + Tcl_DStringLength(&childDString); + while (destString < dEnd) { + if (IS_KANJISTART(UCHAR(*destString))) { + destString += Tcl_KanjiSkip(destString, dEnd, NULL); + continue; + } + if (*destString == '.') { + *destString = '#'; + } + destString++; + } + } + #else for (destString = Tcl_DStringValue(&childDString); *destString != '\0'; destString++) { if (*destString == '.') { *destString = '#'; } } + #endif /* TK_KANJI_OK */ offset = 0; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkMenu.h ./generic/tkMenu.h *** ../../tk8.0.5/generic/tkMenu.h Tue Sep 15 03:23:14 1998 --- ./generic/tkMenu.h Fri Mar 12 00:37:01 1999 *************** *** 14,19 **** --- 14,23 ---- #ifndef _TKMENU #define _TKMENU + #ifdef KANJI + #define TK_KANJI_OK + #endif + #ifndef _TK #include "tk.h" #endif *************** *** 47,54 **** --- 51,63 ---- int type; /* Type of menu entry; see below for * valid types. */ struct TkMenu *menuPtr; /* Menu with which this entry is associated. */ + #ifdef TK_KANJI_OK + wchar *label; /* Main text label displayed in entry (NULL + * if no label). Malloc'ed. */ + #else char *label; /* Main text label displayed in entry (NULL * if no label). Malloc'ed. */ + #endif /* TK_KANJI_OK */ int labelLength; /* Number of non-NULL characters in label. */ Tk_Uid state; /* State of button for display purposes: * normal, active, or disabled. */ *************** *** 65,73 **** --- 74,88 ---- Tk_Image selectImage; /* Image to display in entry when selected, * or NULL if none. Ignored if image is * NULL. */ + #ifdef TK_KANJI_OK + wchar *accel; /* Accelerator string displayed at right + * of menu entry. NULL means no such + * accelerator. Malloc'ed. */ + #else char *accel; /* Accelerator string displayed at right * of menu entry. NULL means no such * accelerator. Malloc'ed. */ + #endif /* TK_KANJI_OK */ int accelLength; /* Number of non-NULL characters in * accelerator. */ int indicatorOn; /* True means draw indicator, false means diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkMenubutton.c ./generic/tkMenubutton.c *** ../../tk8.0.5/generic/tkMenubutton.c Tue Sep 15 03:23:14 1998 --- ./generic/tkMenubutton.c Fri Mar 12 00:37:01 1999 *************** *** 113,120 **** --- 113,125 ---- {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_MENUBUTTON_TAKE_FOCUS, Tk_Offset(TkMenuButton, takeFocus), TK_CONFIG_NULL_OK}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-text", "text", "Text", + DEF_MENUBUTTON_TEXT, Tk_Offset(TkMenuButton, text), 0}, + #else {TK_CONFIG_STRING, "-text", "text", "Text", DEF_MENUBUTTON_TEXT, Tk_Offset(TkMenuButton, text), 0}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_STRING, "-textvariable", "textVariable", "Variable", DEF_MENUBUTTON_TEXT_VARIABLE, Tk_Offset(TkMenuButton, textVarName), TK_CONFIG_NULL_OK}, *************** *** 517,522 **** --- 522,541 ---- char *value; value = Tcl_GetVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY); + #ifdef TK_KANJI_OK + if (value == NULL) { + Tcl_SetVar(interp, mbPtr->textVarName, + Tcl_DecodeWStr(interp, mbPtr->text, NULL), + TCL_GLOBAL_ONLY); + } else { + wchar *old = mbPtr->text; + + mbPtr->text = Tcl_GetWStr(NULL, value, NULL); + if (old != NULL) { + Tcl_FreeWStr(old); + } + } + #else if (value == NULL) { Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, TCL_GLOBAL_ONLY); *************** *** 527,532 **** --- 546,552 ---- mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(mbPtr->text, value); } + #endif Tcl_TraceVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuButtonTextVarProc, (ClientData) mbPtr); *************** *** 790,795 **** --- 810,818 ---- { register TkMenuButton *mbPtr = (TkMenuButton *) clientData; char *value; + #ifdef TK_KANJI_OK + wchar *old = mbPtr->text; + #endif /* TK_KANJI_OK */ /* * If the variable is unset, then immediately recreate it unless *************** *** 798,805 **** --- 821,834 ---- if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { + #ifdef TK_KANJI_OK + Tcl_SetVar(interp, mbPtr->textVarName, + Tcl_DecodeWStr(interp, mbPtr->text, NULL), + TCL_GLOBAL_ONLY); + #else Tcl_SetVar(interp, mbPtr->textVarName, mbPtr->text, TCL_GLOBAL_ONLY); + #endif /* TK_KANJI_OK */ Tcl_TraceVar(interp, mbPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MenuButtonTextVarProc, clientData); *************** *** 811,821 **** --- 840,857 ---- if (value == NULL) { value = ""; } + #ifdef TK_KANJI_OK + mbPtr->text = Tcl_GetWStr(NULL, value, NULL); + if (old != NULL ) { + Tcl_FreeWStr(old); + } + #else if (mbPtr->text != NULL) { ckfree(mbPtr->text); } mbPtr->text = (char *) ckalloc((unsigned) (strlen(value) + 1)); strcpy(mbPtr->text, value); + #endif /* TK_KANJI_OK */ TkpComputeMenuButtonGeometry(mbPtr); if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkMenubutton.h ./generic/tkMenubutton.h *** ../../tk8.0.5/generic/tkMenubutton.h Tue Sep 15 03:23:15 1998 --- ./generic/tkMenubutton.h Fri Mar 12 00:37:02 1999 *************** *** 15,20 **** --- 15,24 ---- #ifndef _TKMENUBUTTON #define _TKMENUBUTTON + #ifdef KANJI + #define TK_KANJI_OK + #endif + #ifndef _TKINT #include "tkInt.h" #endif *************** *** 46,53 **** --- 50,62 ---- * Information about what's displayed in the menu button: */ + #ifdef TK_KANJI_OK + wchar *text; /* Text to display in button (malloc'ed) + * or NULL. */ + #else char *text; /* Text to display in button (malloc'ed) * or NULL. */ + #endif int underline; /* Index of character to underline. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. * If non-NULL, button displays the contents diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkMessage.c ./generic/tkMessage.c *** ../../tk8.0.5/generic/tkMessage.c Tue Sep 15 03:23:15 1998 --- ./generic/tkMessage.c Fri Mar 12 00:37:03 1999 *************** *** 11,19 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkMessage.c,v 1.2 1998/09/14 18:23:15 stanton Exp $ */ #include "tkPort.h" #include "default.h" #include "tkInt.h" --- 11,23 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkMessage.c,v 1.5 1999/03/11 15:37:03 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #include "tkPort.h" #include "default.h" #include "tkInt.h" *************** *** 38,44 **** --- 42,52 ---- * Information used when displaying widget: */ + #ifdef TK_KANJI_OK + wchar *string; /* String displayed in message. */ + #else char *string; /* String displayed in message. */ + #endif /* TK_KANJI_OK */ int numChars; /* Number of characters in string, not * including terminating NULL character. */ char *textVarName; /* Name of variable (malloc'ed) or NULL. *************** *** 148,155 **** --- 156,168 ---- {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus", DEF_MESSAGE_TAKE_FOCUS, Tk_Offset(Message, takeFocus), TK_CONFIG_NULL_OK}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-text", "text", "Text", + DEF_MESSAGE_TEXT, Tk_Offset(Message, string), 0}, + #else {TK_CONFIG_STRING, "-text", "text", "Text", DEF_MESSAGE_TEXT, Tk_Offset(Message, string), 0}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_STRING, "-textvariable", "textVariable", "Variable", DEF_MESSAGE_TEXT_VARIABLE, Tk_Offset(Message, textVarName), TK_CONFIG_NULL_OK}, *************** *** 445,450 **** --- 458,477 ---- char *value; value = Tcl_GetVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY); + #ifdef TK_KANJI_OK + if (value == NULL) { + Tcl_SetVar(interp, msgPtr->textVarName, + Tcl_DecodeWStr(interp, msgPtr->string, NULL), + TCL_GLOBAL_ONLY); + } else { + wchar *old = msgPtr->string; + + msgPtr->string = Tcl_GetWStr(NULL, value, NULL); + if (old != NULL) { + Tcl_FreeWStr(old); + } + } + #else if (value == NULL) { Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string, TCL_GLOBAL_ONLY); *************** *** 454,459 **** --- 481,487 ---- } msgPtr->string = strcpy(ckalloc(strlen(value) + 1), value); } + #endif /* TK_KANJI_OK */ Tcl_TraceVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MessageTextVarProc, (ClientData) msgPtr); *************** *** 465,471 **** --- 493,503 ---- * that couldn't be specified to Tk_ConfigureWidget. */ + #ifdef TK_KANJI_OK + msgPtr->numChars = Tcl_WStrlen(msgPtr->string); + #else msgPtr->numChars = strlen(msgPtr->string); + #endif /* TK_KANJI_OK */ Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border); *************** *** 810,815 **** --- 842,850 ---- { register Message *msgPtr = (Message *) clientData; char *value; + #ifdef TK_KANJI_OK + wchar *old = msgPtr->string; + #endif /* TK_KANJI_OK */ /* * If the variable is unset, then immediately recreate it unless *************** *** 818,825 **** --- 853,866 ---- if (flags & TCL_TRACE_UNSETS) { if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) { + #ifdef TK_KANJI_OK + Tcl_SetVar(interp, msgPtr->textVarName, + Tcl_DecodeWStr(interp, msgPtr->string, NULL), + TCL_GLOBAL_ONLY); + #else Tcl_SetVar(interp, msgPtr->textVarName, msgPtr->string, TCL_GLOBAL_ONLY); + #endif /* TK_KANJI_OK */ Tcl_TraceVar(interp, msgPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MessageTextVarProc, clientData); *************** *** 831,842 **** --- 872,891 ---- if (value == NULL) { value = ""; } + #ifdef TK_KANJI_OK + msgPtr->string = Tcl_GetWStr(NULL, value, NULL); + msgPtr->numChars = Tcl_WStrlen(msgPtr->string); + if (old != NULL) { + Tcl_FreeWStr(old); + } + #else if (msgPtr->string != NULL) { ckfree(msgPtr->string); } msgPtr->numChars = strlen(value); msgPtr->string = (char *) ckalloc((unsigned) (msgPtr->numChars + 1)); strcpy(msgPtr->string, value); + #endif /* TK_KANJI_OK */ ComputeMessageGeometry(msgPtr); if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkScale.c ./generic/tkScale.c *** ../../tk8.0.5/generic/tkScale.c Tue Sep 15 03:23:16 1998 --- ./generic/tkScale.c Fri Mar 12 00:37:06 1999 *************** *** 17,25 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkScale.c,v 1.2 1998/09/14 18:23:16 stanton Exp $ */ #include "tkPort.h" #include "default.h" #include "tkInt.h" --- 17,29 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkScale.c,v 1.5 1999/03/11 15:37:06 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #include "tkPort.h" #include "default.h" #include "tkInt.h" *************** *** 74,81 **** --- 78,90 ---- {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness", "HighlightThickness", DEF_SCALE_HIGHLIGHT_WIDTH, Tk_Offset(TkScale, highlightWidth), 0}, + #ifdef TK_KANJI_OK + {TK_CONFIG_WSTRING, "-label", "label", "Label", + DEF_SCALE_LABEL, Tk_Offset(TkScale, label), TK_CONFIG_NULL_OK}, + #else {TK_CONFIG_STRING, "-label", "label", "Label", DEF_SCALE_LABEL, Tk_Offset(TkScale, label), TK_CONFIG_NULL_OK}, + #endif /* TK_KANJI_OK */ {TK_CONFIG_PIXELS, "-length", "length", "Length", DEF_SCALE_LENGTH, Tk_Offset(TkScale, length), 0}, {TK_CONFIG_UID, "-orient", "orient", "Orient", *************** *** 581,587 **** --- 590,600 ---- TkpSetScaleValue(scalePtr, scalePtr->value, 1, 1); if (scalePtr->label != NULL) { + #ifdef TK_KANJI_OK + scalePtr->labelLength = Tcl_WStrlen(scalePtr->label); + #else scalePtr->labelLength = strlen(scalePtr->label); + #endif /* TK_KANJI_OK */ } else { scalePtr->labelLength = 0; } *************** *** 843,848 **** --- 856,865 ---- * use whichever length is longer. */ + #if defined(KANJI) && defined(TK_KANJI_OK) && defined(TK_REPLACE_TO_KANJIFUNC) + #undef Tk_TextWidth + #endif /* KANJI && TK_KANJI_OK && TK_REPLACE_TO_KANJIFUNC */ + sprintf(valueString, scalePtr->format, scalePtr->fromValue); valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1); *************** *** 851,856 **** --- 868,877 ---- if (valuePixels < tmp) { valuePixels = tmp; } + + #if defined(KANJI) && defined(TK_KANJI_OK) && defined(TK_REPLACE_TO_KANJIFUNC) + #define Tk_TextWidth Tk_WTextWidth + #endif /* KANJI && TK_KANJI_OK && TK_REPLACE_TO_KANJIFUNC */ /* * Assign x-locations to the elements of the scale, working from diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkScale.h ./generic/tkScale.h *** ../../tk8.0.5/generic/tkScale.h Tue Sep 15 03:23:17 1998 --- ./generic/tkScale.h Fri Mar 12 00:37:06 1999 *************** *** 15,20 **** --- 15,24 ---- #ifndef _TKSCALE #define _TKSCALE + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ + #ifndef _TK #include "tk.h" #endif *************** *** 75,83 **** --- 79,93 ---- int repeatDelay; /* How long to wait before auto-repeating * on scrolling actions (in ms). */ int repeatInterval; /* Interval between autorepeats (in ms). */ + #ifdef TK_KANJI_OK + wchar *label; /* Label to display above or to right of + * scale; NULL means don't display a + * label. Malloc'ed. */ + #else char *label; /* Label to display above or to right of * scale; NULL means don't display a * label. Malloc'ed. */ + #endif /* TK_KANJI_OK */ int labelLength; /* Number of non-NULL chars. in label. */ Tk_Uid state; /* Normal or disabled. Value cannot be * changed when scale is disabled. */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkSelect.c ./generic/tkSelect.c *** ../../tk8.0.5/generic/tkSelect.c Tue Sep 15 03:23:17 1998 --- ./generic/tkSelect.c Thu Mar 18 22:38:41 1999 *************** *** 58,63 **** --- 58,67 ---- static int HandleTclCommand _ANSI_ARGS_((ClientData clientData, int offset, char *buffer, int maxBytes)); + #ifdef KANJI + static int HandleTclCommandCtext _ANSI_ARGS_((ClientData clientData, + int offset, char *buffer, int maxBytes)); + #endif /* KANJI */ static void LostSelection _ANSI_ARGS_((ClientData clientData)); static int SelGetProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *portion)); *************** *** 152,158 **** --- 156,167 ---- * callback to allow other clients to do this too? */ + #ifdef KANJI + if (selPtr->proc == HandleTclCommand || + selPtr->proc == HandleTclCommandCtext) { + #else if (selPtr->proc == HandleTclCommand) { + #endif /* KANJI */ ckfree((char *) selPtr->clientData); } break; *************** *** 163,169 **** --- 172,188 ---- selPtr->format = format; selPtr->proc = proc; selPtr->clientData = clientData; + #ifdef KANJI + if (format == XA_STRING || + format == Tk_UsefulAtom(winPtr, compoundTextAtom) || + format == Tk_UsefulAtom(winPtr, cStringAtom) || + /* + * format TEXT is not valid, but size must be 8. + */ + format == Tk_UsefulAtom(winPtr, textAtom)) { + #else if (format == XA_STRING) { + #endif /* KANJI */ selPtr->size = 8; } else { selPtr->size = 32; *************** *** 235,241 **** --- 254,265 ---- } else { prevPtr->nextPtr = selPtr->nextPtr; } + #ifdef KANJI + if (selPtr->proc == HandleTclCommand || + selPtr->proc == HandleTclCommandCtext) { + #else if (selPtr->proc == HandleTclCommand) { + #endif /* KANJI */ ckfree((char *) selPtr->clientData); } ckfree((char *) selPtr); *************** *** 480,485 **** --- 504,514 ---- TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkSelectionInfo *infoPtr; + #ifdef KANJI + int result = TCL_ERROR; + int doConv = 0; + Atom type = None; + #endif /* KANJI */ if (dispPtr->multipleAtom == None) { TkSelInit(tkwin); *************** *** 500,506 **** --- 529,539 ---- } if (infoPtr != NULL) { register TkSelHandler *selPtr; + #ifdef KANJI + int offset, count; + #else int offset, result, count; + #endif /* KANJI */ char buffer[TK_SEL_BYTES_AT_ONCE+1]; TkSelInProgress ip; *************** *** 512,518 **** --- 545,553 ---- } } if (selPtr == NULL) { + #ifndef KANJI Atom type; + #endif /* !KANJI */ count = TkSelDefaultSelection(infoPtr, target, buffer, TK_SEL_BYTES_AT_ONCE, &type); *************** *** 549,554 **** --- 584,599 ---- offset += count; } pendingPtr = ip.nextPtr; + #ifdef KANJI + if (selPtr->format == Tk_UsefulAtom(((TkWindow *)tkwin), compoundTextAtom) && + proc == SelGetProc) { + doConv = 1; + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: selection (within proc) do convert.\n"); + #endif /* SELECTION_DEBUG */ + goto ConvIt; + } + #endif /* KANJI */ } return result; } *************** *** 557,564 **** --- 602,641 ---- * The selection is owned by some other process. */ + #ifdef KANJI + result = TkSelGetSelection(interp, tkwin, selection, target, proc, + clientData, &type); + if (proc == SelGetProc && + type == Tk_UsefulAtom(((TkWindow *)tkwin), compoundTextAtom)) { + doConv = 1; + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: selection (other proc) do convert.\n"); + #endif /* SELECTION_DEBUG */ + } + #else return TkSelGetSelection(interp, tkwin, selection, target, proc, clientData); + #endif /* KANJI */ + #ifdef KANJI + ConvIt: + if (result == TCL_OK && doConv == 1) { + Tcl_DString *dStr = (Tcl_DString *)clientData; + wchar *ws = Tk_CtextToWStr(Tcl_DStringValue(dStr), + Tcl_DStringLength(dStr)); + if (ws != NULL) { + int kanjiCode = Tcl_KanjiCode(interp); + int count = Tcl_KanjiDecode(kanjiCode, ws, NULL); + char *newStr = (char *)ckalloc((unsigned int)(count + 1)); + (void)Tcl_KanjiDecode(kanjiCode, ws, newStr); + newStr[count] = '\0'; + (void)ckfree((char *)ws); + Tcl_DStringFree(dStr); + Tcl_DStringAppend(dStr, newStr, -1); + (void)ckfree((char *)newStr); + } + } + return result; + #endif /* KANJI */ cantget: Tcl_AppendResult(interp, Tk_GetAtomName(tkwin, selection), *************** *** 704,715 **** --- 781,834 ---- } else if (targetName != NULL) { target = Tk_InternAtom(tkwin, targetName); } else { + #ifdef KANJI + /* + * As a decent client, it should be a TEXT. + */ + target = Tk_UsefulAtom(tkwin, textAtom); + #else target = XA_STRING; + #endif /* KANJI */ } Tcl_DStringInit(&selBytes); + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: try get sel:'%s' target:'%s'\n", + Tk_GetAtomName(tkwin, selection), + Tk_GetAtomName(tkwin, target)); + #endif /* SELECTION_DEBUG */ result = Tk_GetSelection(interp, tkwin, selection, target, SelGetProc, (ClientData) &selBytes); + #ifdef KANJI + if (result != TCL_OK && targetName == NULL && count != 1) { + /* + * Try COMPOUND_TEXT. + */ + Tcl_ResetResult(interp); + target = Tk_UsefulAtom(tkwin, compoundTextAtom); + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: try get sel:'%s' target:'%s'\n", + Tk_GetAtomName(tkwin, selection), + Tk_GetAtomName(tkwin, target)); + #endif /* SELECTION_DEBUG */ + result = Tk_GetSelection(interp, tkwin, selection, target, SelGetProc, + (ClientData) &selBytes); + if (result != TCL_OK) { + /* + * Try STRING. + */ + Tcl_ResetResult(interp); + target = XA_STRING; + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: try get sel:'%s' target:'%s'\n", + Tk_GetAtomName(tkwin, selection), + Tk_GetAtomName(tkwin, target)); + #endif /* SELECTION_DEBUG */ + result = Tk_GetSelection(interp, tkwin, selection, target, SelGetProc, + (ClientData) &selBytes); + } + } + #endif /* KANJI */ if (result == TCL_OK) { Tcl_DStringResult(interp, &selBytes); } else { *************** *** 769,782 **** --- 888,922 ---- } else if (targetName != NULL) { target = Tk_InternAtom(tkwin, targetName); } else { + #ifdef KANJI + /* + * TEXT should be a default. + */ + target = Tk_UsefulAtom(tkwin, textAtom); + #else target = XA_STRING; + #endif /* KANJI */ } if (count > 3) { format = Tk_InternAtom(tkwin, args[3]); } else if (formatName != NULL) { format = Tk_InternAtom(tkwin, formatName); } else { + #ifdef KANJI + if (target == Tk_UsefulAtom(tkwin, textAtom) || + target == Tk_UsefulAtom(tkwin, compoundTextAtom)) { + /* + * Default format is COMPOUND_TEXT. + */ + format = Tk_UsefulAtom(tkwin, compoundTextAtom); + } else if (target == Tk_UsefulAtom(tkwin, cStringAtom)) { + format = Tk_UsefulAtom(tkwin, cStringAtom); + } else { + format = XA_STRING; + } + #else format = XA_STRING; + #endif /* KANJI */ } cmdLength = strlen(args[1]); if (cmdLength == 0) { *************** *** 787,792 **** --- 927,946 ---- cmdInfoPtr->interp = interp; cmdInfoPtr->cmdLength = cmdLength; strcpy(cmdInfoPtr->command, args[1]); + #ifdef KANJI + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: create sel handler selection:'%s' target:'%s' format:'%s'\n", + Tk_GetAtomName(tkwin, selection), + Tk_GetAtomName(tkwin, target), + Tk_GetAtomName(tkwin, format)); + #endif + if (format == Tk_UsefulAtom(tkwin, compoundTextAtom) || + format == Tk_UsefulAtom(tkwin, textAtom)) { + Tk_CreateSelHandler(tkwin, selection, target, HandleTclCommandCtext, + (ClientData) cmdInfoPtr, + Tk_UsefulAtom(tkwin, compoundTextAtom)); + } else + #endif /* KANJI */ Tk_CreateSelHandler(tkwin, selection, target, HandleTclCommand, (ClientData) cmdInfoPtr, format); } *************** *** 924,930 **** --- 1078,1089 ---- ipPtr->selPtr = NULL; } } + #ifdef KANJI + if (selPtr->proc == HandleTclCommand || + selPtr->proc == HandleTclCommandCtext) { + #else /* KANJI */ if (selPtr->proc == HandleTclCommand) { + #endif /* KANJI */ ckfree((char *) selPtr->clientData); } ckfree((char *) selPtr); *************** *** 986,991 **** --- 1145,1153 ---- dispPtr->timestampAtom = Tk_InternAtom(tkwin, "TIMESTAMP"); dispPtr->textAtom = Tk_InternAtom(tkwin, "TEXT"); dispPtr->compoundTextAtom = Tk_InternAtom(tkwin, "COMPOUND_TEXT"); + #ifdef KANJI + dispPtr->cStringAtom = Tk_InternAtom(tkwin, "C_STRING"); + #endif /* KANJI */ dispPtr->applicationAtom = Tk_InternAtom(tkwin, "TK_APPLICATION"); dispPtr->windowAtom = Tk_InternAtom(tkwin, "TK_WINDOW"); dispPtr->clipboardAtom = Tk_InternAtom(tkwin, "CLIPBOARD"); *************** *** 1173,1178 **** --- 1335,1433 ---- Tcl_Release((ClientData) interp); return length; } + + #ifdef KANJI + /* + *---------------------------------------------------------------------- + * + * HandleTclCommandCtext -- + * + * This procedure is same as HandleTclCommand except it + * converts the result string to COMPOUND_TEXT before passing + * to the selection requestor. + * + * Results: + * See HandleTclCommand. + * + * Side effects: + * None except for things done by the Tcl command. + * + *---------------------------------------------------------------------- + */ + + static int + HandleTclCommandCtext(clientData, offset, buffer, maxBytes) + ClientData clientData; /* Information about command to execute. */ + int offset; /* Return selection bytes starting at this + * offset. */ + char *buffer; /* Place to store converted selection. */ + int maxBytes; /* Maximum # of bytes to store at buffer. */ + { + CommandInfo *cmdInfoPtr = (CommandInfo *) clientData; + int spaceNeeded, length; + #define MAX_STATIC_SIZE 100 + char staticSpace[MAX_STATIC_SIZE]; + char *command; + Tcl_Interp *interp; + Tcl_DString oldResult; + int kanjiCode = Tcl_KanjiCode(cmdInfoPtr->interp); + + /* + * We must copy the interpreter pointer from CommandInfo because the + * command could delete the handler, freeing the CommandInfo data before we + * are done using it. + */ + + interp = cmdInfoPtr->interp; + + /* + * First, generate a command by taking the command string + * and appending the offset and maximum # of bytes. + */ + + spaceNeeded = cmdInfoPtr->cmdLength + 30; + if (spaceNeeded < MAX_STATIC_SIZE) { + command = staticSpace; + } else { + command = (char *) ckalloc((unsigned) spaceNeeded); + } + sprintf(command, "%s %d %d", cmdInfoPtr->command, offset, maxBytes); + + /* + * Execute the command. Be sure to restore the state of the + * interpreter after executing the command. + */ + + Tcl_DStringInit(&oldResult); + Tcl_DStringGetResult(interp, &oldResult); + if (Tcl_GlobalEval(interp, command) == TCL_OK) { + char *result = interp->result; + int count = Tcl_KanjiEncode(kanjiCode, result, NULL); + wchar *wstr = (wchar *)ckalloc(sizeof(wchar) * (unsigned)(count + 1)); + + (void) Tcl_KanjiEncode(kanjiCode, result, wstr); + result = Tk_WStrToCtext(wstr, -1); + ckfree((char *)wstr); + + length = (result == NULL) ? 0 : strlen(result); + if (length > maxBytes) { + length = maxBytes; + } + memcpy((VOID *) buffer, (VOID *) result, (unsigned int)length); + buffer[length] = '\0'; + if (result != NULL) ckfree(result); + } else { + length = -1; + } + Tcl_DStringResult(interp, &oldResult); + + if (command != staticSpace) { + ckfree(command); + } + + return length; + } + #endif /* KANJI */ /* *---------------------------------------------------------------------- diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkSelect.h ./generic/tkSelect.h *** ../../tk8.0.5/generic/tkSelect.h Tue Sep 15 03:23:17 1998 --- ./generic/tkSelect.h Thu Mar 18 22:38:41 1999 *************** *** 84,89 **** --- 84,92 ---- Atom selection; /* Selection being requested. */ Atom property; /* Property where selection will appear. */ Atom target; /* Desired form for selection. */ + #ifdef KANJI + Atom type; /* return'd type of the selection. */ + #endif /* KANJI */ int (*proc) _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *portion)); /* Procedure to call to handle pieces * of selection. */ *************** *** 173,181 **** --- 176,191 ---- extern int TkSelDefaultSelection _ANSI_ARGS_(( TkSelectionInfo *infoPtr, Atom target, char *buffer, int maxBytes, Atom *typePtr)); + #ifdef KANJI + extern int TkSelGetSelection _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, Atom selection, Atom target, + Tk_GetSelProc *proc, ClientData clientData, + Atom *typeAtomPtr)); + #else extern int TkSelGetSelection _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData)); + #endif /* KANJI */ #ifndef TkSelUpdateClipboard extern void TkSelUpdateClipboard _ANSI_ARGS_((TkWindow *winPtr, TkClipboardTarget *targetPtr)); diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkText.c ./generic/tkText.c *** ../../tk8.0.5/generic/tkText.c Tue Sep 15 03:23:17 1998 --- ./generic/tkText.c Fri Mar 12 00:37:09 1999 *************** *** 13,21 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkText.c,v 1.2 1998/09/14 18:23:17 stanton Exp $ */ #include "default.h" #include "tkPort.h" #include "tkInt.h" --- 13,25 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkText.c,v 1.12 1999/03/11 15:37:09 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif + #include "default.h" #include "tkPort.h" #include "tkInt.h" *************** *** 170,175 **** --- 174,186 ---- int offset, char *buffer, int maxBytes)); static int TextSearchCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int argc, char **argv)); + #ifdef TK_KANJI_OK + static int TextFetchSelectionCtext _ANSI_ARGS_(( + ClientData clientData, + int offset, char *buffer, int maxBytes)); + static int KanjiTextSearchCmd _ANSI_ARGS_((TkText *textPtr, + Tcl_Interp *interp, int argc, char **argv)); + #endif /* TK_KANJI_OK */ static int TextWidgetCmd _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, int argc, char **argv)); static void TextWorldChanged _ANSI_ARGS_(( *************** *** 339,344 **** --- 350,367 ---- TkTextBindProc, (ClientData) textPtr); Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING, TextFetchSelection, (ClientData) textPtr, XA_STRING); + #ifdef TK_KANJI_OK + Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(textPtr->tkwin, textAtom), + TextFetchSelectionCtext, + (ClientData) textPtr, + Tk_UsefulAtom(textPtr->tkwin, compoundTextAtom)); + Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, + Tk_UsefulAtom(textPtr->tkwin, compoundTextAtom), + TextFetchSelectionCtext, + (ClientData) textPtr, + Tk_UsefulAtom(textPtr->tkwin, compoundTextAtom)); + #endif /* TK_KANJI_OK */ if (ConfigureText(interp, textPtr, argc-2, argv+2, 0) != TCL_OK) { Tk_DestroyWindow(textPtr->tkwin); return TCL_ERROR; *************** *** 543,549 **** --- 566,579 ---- goto done; } while (1) { + #ifdef TK_KANJI_OK + int offset, last; + wchar savedChar; + int length, kanjiCode = Tcl_KanjiCode(interp); + char *str; + #else int offset, last, savedChar; + #endif /* TK_KANJI_OK */ TkTextSegment *segPtr; segPtr = TkTextIndexToSeg(&index1, &offset); *************** *** 562,569 **** --- 592,607 ---- if (segPtr->typePtr == &tkTextCharType) { savedChar = segPtr->body.chars[last]; segPtr->body.chars[last] = 0; + #ifdef TK_KANJI_OK + length = Tcl_KanjiDecode(kanjiCode, segPtr->body.chars+offset, NULL); + str = (char *) ckalloc((unsigned)(length + 1)); + (void) Tcl_KanjiDecode(kanjiCode, segPtr->body.chars+offset, str); + Tcl_AppendResult(interp, str, (char *) NULL); + ckfree(str); + #else Tcl_AppendResult(interp, segPtr->body.chars + offset, (char *) NULL); + #endif /* TK_KANJI_OK */ segPtr->body.chars[last] = savedChar; } TkTextIndexForwChars(&index1, last-offset, &index1); *************** *** 587,592 **** --- 625,633 ---- int i, j, numTags; char **tagNames; TkTextTag **oldTagArrayPtr; + #ifdef TK_KANJI_OK + wchar *wstr; + #endif /* TK_KANJI_OK */ if (argc < 4) { Tcl_AppendResult(interp, "wrong # args: should be \"", *************** *** 604,611 **** --- 645,659 ---- for (j = 3; j < argc; j += 2) { InsertChars(textPtr, &index1, argv[j]); if (argc > (j+1)) { + #ifdef TK_KANJI_OK + wstr = Tcl_GetWStr(NULL, argv[j], NULL); + TkTextIndexForwChars(&index1, (int) Tcl_WStrlen(wstr), + &index2); + Tcl_FreeWStr(wstr); + #else TkTextIndexForwChars(&index1, (int) strlen(argv[j]), &index2); + #endif /* TK_KANJI_OK */ oldTagArrayPtr = TkBTreeGetTags(&index1, &numTags); if (oldTagArrayPtr != NULL) { for (i = 0; i < numTags; i++) { *************** *** 637,643 **** --- 685,706 ---- result = TkTextScanCmd(textPtr, interp, argc, argv); } else if ((c == 's') && (strcmp(argv[1], "search") == 0) && (length >= 3)) { + #ifdef TK_KANJI_OK + int i, kanjiCode = TCL_ANY; + int aLen; + for (i = 2; i < argc; i++) { + if (argv[i][0] == '-') continue; + aLen = strlen(argv[i]); + if (Tcl_KanjiString(interp, argv[i], argv[i] + aLen, &kanjiCode) != TCL_NOT_KANJI) break; + } + if (kanjiCode == TCL_ANY) { + result = TextSearchCmd(textPtr, interp, argc, argv); + } else { + result = KanjiTextSearchCmd(textPtr, interp, argc, argv); + } + #else result = TextSearchCmd(textPtr, interp, argc, argv); + #endif /* TK_KANJI_OK */ } else if ((c == 's') && (strcmp(argv[1], "see") == 0) && (length >= 3)) { result = TkTextSeeCmd(textPtr, interp, argc, argv); } else if ((c == 't') && (strcmp(argv[1], "tag") == 0)) { *************** *** 646,651 **** --- 709,728 ---- result = TkTextWindowCmd(textPtr, interp, argc, argv); } else if ((c == 'x') && (strncmp(argv[1], "xview", length) == 0)) { result = TkTextXviewCmd(textPtr, interp, argc, argv); + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + } else if ((c == 'x') && (strncmp(argv[1], "xypos", length) == 0)) { + if (argc != 3) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " xypos index\"", (char *) NULL); + result = TCL_ERROR; + goto done; + } + if (TkTextGetIndex(interp, textPtr, argv[2], &index1) != TCL_OK || + TkTextXYPos(interp, textPtr, &index1) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ } else if ((c == 'y') && (strncmp(argv[1], "yview", length) == 0) && (length >= 2)) { result = TkTextYviewCmd(textPtr, interp, argc, argv); *************** *** 653,659 **** --- 730,740 ---- Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be bbox, cget, compare, configure, debug, delete, ", "dlineinfo, get, image, index, insert, mark, scan, search, see, ", + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + "tag, window, xview, xypos, or yview", + #else "tag, window, xview, or yview", + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ (char *) NULL); result = TCL_ERROR; } *************** *** 938,944 **** --- 1019,1032 ---- textPtr = (TkText *) instanceData; + #ifdef TK_KANJI_OK + { + wchar wTmp = '0'; + textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, &wTmp, 1); + } + #else textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1); + #endif /* TK_KANJI_OK */ if (textPtr->charWidth <= 0) { textPtr->charWidth = 1; } *************** *** 1338,1343 **** --- 1426,1435 ---- int count, chunkSize, offsetInSeg; TkTextSearch search; TkTextSegment *segPtr; + #ifdef TK_KANJI_OK + char *str; + int numBytes; + #endif /* TK_KANJI_OK */ if (!textPtr->exportSelection) { return -1; *************** *** 1398,1406 **** --- 1490,1511 ---- } segPtr = TkTextIndexToSeg(&textPtr->selIndex, &offsetInSeg); chunkSize = segPtr->size - offsetInSeg; + #ifdef TK_KANJI_OK + str = Tk_WStrToString(segPtr->body.chars+offsetInSeg, chunkSize); + numBytes = ((str == NULL) ? 0 : strlen(str)); + if (offset > numBytes) { + offset -= numBytes; + goto next; + } + numBytes -= offset; + if (numBytes > maxBytes) { + numBytes = maxBytes; + } + #else if (chunkSize > maxBytes) { chunkSize = maxBytes; } + #endif /* TK_KANJI_OK */ if (textPtr->selIndex.linePtr == search.curIndex.linePtr) { int leftInRange; *************** *** 1409,1427 **** --- 1514,1701 ---- if (leftInRange < chunkSize) { chunkSize = leftInRange; if (chunkSize <= 0) { + #ifdef TK_KANJI_OK + if (str != NULL) ckfree(str); + #endif /* TK_KANJI_OK */ break; } } } if (segPtr->typePtr == &tkTextCharType) { + #ifdef TK_KANJI_OK + memcpy((VOID *) buffer, (VOID *) (str + offset), (size_t) numBytes); + offset = 0; + + buffer += numBytes; + maxBytes -= numBytes; + count += numBytes; + #else memcpy((VOID *) buffer, (VOID *) (segPtr->body.chars + offsetInSeg), (size_t) chunkSize); buffer += chunkSize; maxBytes -= chunkSize; count += chunkSize; + #endif /* TK_KANJI_OK */ + } + #ifdef TK_KANJI_OK + next: + if (str != NULL) ckfree(str); + if (maxBytes > 0) { + TkTextIndexForwChars(&textPtr->selIndex, chunkSize, + &textPtr->selIndex); } + #else TkTextIndexForwChars(&textPtr->selIndex, chunkSize, &textPtr->selIndex); + #endif /* TK_KANJI_OK */ + } + + /* + * Find the beginning of the next range of selected text. + */ + + if (!TkBTreeNextTag(&search)) { + break; + } + textPtr->selIndex = search.curIndex; + } + + done: + *buffer = 0; + return count; + } + #ifdef TK_KANJI_OK + + /* + *---------------------------------------------------------------------- + * + * TextFetchSelectionCtext -- + * + * This procedure is similar to TextFetchSelection except + * it converts the selection to COMPOUND_TEXT before + * passing it to the requester. + * + * Results: + * See TextFetchSelection. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + static int + TextFetchSelectionCtext(clientData, offset, buffer, maxBytes) + ClientData clientData; /* Information about text widget. */ + int offset; /* Offset within selection of first + * character to be returned. */ + char *buffer; /* Location in which to place + * selection. */ + int maxBytes; /* Maximum number of bytes to place + * at buffer, not including terminating + * NULL character. */ + { + register TkText *textPtr = (TkText *) clientData; + TkTextIndex eof; + int count, chunkSize, offsetInSeg; + TkTextSearch search; + TkTextSegment *segPtr; + char *str; + int numBytes; + + if (!textPtr->exportSelection) { + return -1; + } + + /* + * Find the beginning of the next range of selected text. Note: if + * the selection is being retrieved in multiple pieces (offset != 0) + * and some modification has been made to the text that affects the + * selection then reject the selection request (make 'em start over + * again). + */ + + if (offset != 0 && textPtr->abortSelections) return 0; + TkTextMakeIndex(textPtr->tree, 0, 0, &textPtr->selIndex); + textPtr->abortSelections = 0; + TkTextMakeIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree), 0, &eof); + TkBTreeStartSearch(&textPtr->selIndex, &eof, textPtr->selTagPtr, &search); + if (!TkBTreeCharTagged(&textPtr->selIndex, textPtr->selTagPtr)) { + if (!TkBTreeNextTag(&search)) { + if (offset == 0) { + return -1; + } else { + return 0; + } + } + textPtr->selIndex = search.curIndex; + } + + /* + * Each iteration through the outer loop below scans one selected range. + * Each iteration through the inner loop scans one segment in the + * selected range. + */ + + count = 0; + while (1) { + /* + * Find the end of the current range of selected text. + */ + + if (!TkBTreeNextTag(&search)) { + panic("TextFetchSelection couldn't find end of range"); + } + + /* + * Copy information from character segments into the buffer + * until either we run out of space in the buffer or we get + * to the end of this range of text. + */ + + while (1) { + if (maxBytes == 0) { + goto done; + } + segPtr = TkTextIndexToSeg(&textPtr->selIndex, &offsetInSeg); + chunkSize = segPtr->size - offsetInSeg; + str = Tk_WStrToCtext(segPtr->body.chars+offsetInSeg, chunkSize); + numBytes = ((str == NULL) ? 0 : strlen(str)); + if (offset > numBytes) { + offset -= numBytes; + goto next; + } + numBytes -= offset; + if (numBytes > maxBytes) { + numBytes = maxBytes; + } + if (textPtr->selIndex.linePtr == search.curIndex.linePtr) { + int leftInRange; + + leftInRange = search.curIndex.charIndex + - textPtr->selIndex.charIndex; + if (leftInRange < chunkSize) { + chunkSize = leftInRange; + if (chunkSize <= 0) { + if (str != NULL) ckfree(str); + break; + } + } + } + if (segPtr->typePtr == &tkTextCharType) { + memcpy((VOID *) buffer, (VOID *) (str + offset), (size_t) numBytes); + offset = 0; + + buffer += numBytes; + maxBytes -= numBytes; + count += numBytes; + } + next: + if (str != NULL) ckfree(str); + if (maxBytes > 0) { + TkTextIndexForwChars(&textPtr->selIndex, chunkSize, + &textPtr->selIndex); + } } /* *************** *** 1438,1443 **** --- 1712,1718 ---- *buffer = 0; return count; } + #endif /* TK_KANJI_OK */ /* *---------------------------------------------------------------------- *************** *** 1704,1713 **** --- 1979,2002 ---- linePtr = TkBTreeFindLine(textPtr->tree, lineNum); for (segPtr = linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { + #ifdef TK_KANJI_OK + int i; + char *str; + #endif /* TK_KANJI_OK */ if (segPtr->typePtr != &tkTextCharType) { continue; } + #ifdef TK_KANJI_OK + str = ckalloc((unsigned) (segPtr->size + 1)); + for (i = 0; i < segPtr->size; i++) { + str[i] = (char) segPtr->body.chars[i]; + } + str[segPtr->size] = 0; + Tcl_DStringAppend(&line, str, (int)strlen(str)); + ckfree(str); + #else Tcl_DStringAppend(&line, segPtr->body.chars, segPtr->size); + #endif /* TK_KANJI_OK */ } if (!exact) { Tcl_DStringSetLength(&line, Tcl_DStringLength(&line)-1); *************** *** 1894,1899 **** --- 2183,2628 ---- } return code; } + #ifdef TK_KANJI_OK + + /* + *---------------------------------------------------------------------- + * + * KanjiTextSearchCmd -- + * + * This procedure is invoked to process the "search" widget command + * for text widgets. See the user documentation for details on what + * it does. This procedure is copied from "TextSearchCmd" and + * modified for the kanji characters. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *---------------------------------------------------------------------- + */ + + static int + KanjiTextSearchCmd(textPtr, interp, argc, argv) + TkText *textPtr; /* Information about text widget. */ + Tcl_Interp *interp; /* Current interpreter. */ + int argc; /* Number of arguments. */ + char **argv; /* Argument strings. */ + { + int backwards, exact, c, i, argsLeft, noCase, leftToScan; + size_t length; + int numLines, startingLine, startingChar, lineNum, firstChar, lastChar; + int code, matchLength, matchChar, passes, stopLine, searchWholeText; + int patLength; + #ifdef TK_KANJI_OK + char *arg, *varName; + wchar *pattern, *pPattern, *p, *startOfLine; + #else + char *arg, *pattern, *varName, *p, *startOfLine; + #endif /* TK_KANJI_OK */ + char buffer[20]; + TkTextIndex index, stopIndex; + #ifdef TK_KANJI_OK + Tcl_DWString line, patDString; + #else + Tcl_DString line, patDString; + #endif /* TK_KANJI_OK */ + TkTextSegment *segPtr; + TkTextLine *linePtr; + #ifndef TK_KANJI_OK + Tcl_RegExp regexp = NULL; /* Initialization needed only to + * prevent compiler warning. */ + #endif /* !TK_KANJI_OK */ + + /* + * Parse switches and other arguments. + */ + + exact = 1; + backwards = 0; + noCase = 0; + varName = NULL; + for (i = 2; i < argc; i++) { + arg = argv[i]; + if (arg[0] != '-') { + break; + } + length = strlen(arg); + if (length < 2) { + badSwitch: + Tcl_AppendResult(interp, "bad switch \"", arg, + "\": must be -forward, -backward, -exact, -regexp, ", + "-nocase, -count, or --", (char *) NULL); + return TCL_ERROR; + } + c = arg[1]; + if ((c == 'b') && (strncmp(argv[i], "-backwards", length) == 0)) { + backwards = 1; + } else if ((c == 'c') && (strncmp(argv[i], "-count", length) == 0)) { + if (i >= (argc-1)) { + interp->result = "no value given for \"-count\" option"; + return TCL_ERROR; + } + i++; + varName = argv[i]; + } else if ((c == 'e') && (strncmp(argv[i], "-exact", length) == 0)) { + exact = 1; + } else if ((c == 'f') && (strncmp(argv[i], "-forwards", length) == 0)) { + backwards = 0; + } else if ((c == 'n') && (strncmp(argv[i], "-nocase", length) == 0)) { + noCase = 1; + } else if ((c == 'r') && (strncmp(argv[i], "-regexp", length) == 0)) { + #ifdef TK_KANJI_OK + interp->result = "-regexp is not available for kanji characters"; + return TCL_ERROR; + #endif /* TK_KANJI_OK */ + exact = 0; + } else if ((c == '-') && (strncmp(argv[i], "--", length) == 0)) { + i++; + break; + } else { + goto badSwitch; + } + } + argsLeft = argc - (i+2); + if ((argsLeft != 0) && (argsLeft != 1)) { + Tcl_AppendResult(interp, "wrong # args: should be \"", + argv[0], " search ?switches? pattern index ?stopIndex?", + (char *) NULL); + return TCL_ERROR; + } + #ifdef TK_KANJI_OK + pattern = pPattern = Tcl_GetWStr(NULL, argv[i], NULL); + #else + pattern = argv[i]; + #endif /* TK_KANJI_OK */ + + /* + * Convert the pattern to lower-case if we're supposed to ignore case. + */ + + if (noCase) { + #ifdef TK_KANJI_OK + Tcl_DWStringInit(&patDString); + Tcl_DWStringAppend(&patDString, pattern, -1); + pattern = Tcl_DWStringValue(&patDString); + for (p = pattern; *p != 0; p++) { + if (ISWUPPER(*p)) { + *p = (wchar) tolower(UCHAR(*p)); + } + } + #else + Tcl_DStringInit(&patDString); + Tcl_DStringAppend(&patDString, pattern, -1); + pattern = Tcl_DStringValue(&patDString); + for (p = pattern; *p != 0; p++) { + if (isupper(UCHAR(*p))) { + *p = tolower(UCHAR(*p)); + } + } + #endif /* TK_KANJI_OK */ + } + + if (TkTextGetIndex(interp, textPtr, argv[i+1], &index) != TCL_OK) { + #ifdef TK_KANJI_OK + Tcl_FreeWStr(pPattern); + if (noCase) { + Tcl_DWStringFree(&patDString); + } + #endif /* TK_KANJI_OK */ + return TCL_ERROR; + } + numLines = TkBTreeNumLines(textPtr->tree); + startingLine = TkBTreeLineIndex(index.linePtr); + startingChar = index.charIndex; + if (startingLine >= numLines) { + startingLine = 0; + startingChar = 0; + } + if (argsLeft == 1) { + if (TkTextGetIndex(interp, textPtr, argv[i+2], &stopIndex) != TCL_OK) { + #ifdef TK_KANJI_OK + Tcl_FreeWStr(pPattern); + if (noCase) { + Tcl_DWStringFree(&patDString); + } + #endif /* TK_KANJI_OK */ + return TCL_ERROR; + } + stopLine = TkBTreeLineIndex(stopIndex.linePtr); + if (!backwards && (stopLine == numLines)) { + stopLine = numLines-1; + } + searchWholeText = 0; + } else { + stopLine = 0; + searchWholeText = 1; + } + + /* + * Scan through all of the lines of the text circularly, starting + * at the given index. + */ + + matchLength = patLength = 0; /* Only needed to prevent compiler + * warnings. */ + if (exact) { + #ifdef TK_KANJI_OK + patLength = Tcl_WStrlen(pattern); + #else + patLength = strlen(pattern); + #endif /* TK_KANJI_OK */ + } else { + #ifdef TK_KANJI_OK + #else + regexp = Tcl_RegExpCompile(interp, pattern); + if (regexp == NULL) { + return TCL_ERROR; + } + #endif /* TK_KANJI_OK */ + } + lineNum = startingLine; + code = TCL_OK; + #ifdef TK_KANJI_OK + Tcl_DWStringInit(&line); + #else + Tcl_DStringInit(&line); + #endif /* TK_KANJI_OK */ + for (passes = 0; passes < 2; ) { + if (lineNum >= numLines) { + /* + * Don't search the dummy last line of the text. + */ + + goto nextLine; + } + + /* + * Extract the text from the line. If we're doing regular + * expression matching, drop the newline from the line, so + * that "$" can be used to match the end of the line. + */ + + linePtr = TkBTreeFindLine(textPtr->tree, lineNum); + for (segPtr = linePtr->segPtr; segPtr != NULL; + segPtr = segPtr->nextPtr) { + if (segPtr->typePtr != &tkTextCharType) { + continue; + } + #ifdef TK_KANJI_OK + Tcl_DWStringAppend(&line, segPtr->body.chars, segPtr->size); + #else + Tcl_DStringAppend(&line, segPtr->body.chars, segPtr->size); + #endif /* TK_KANJI_OK */ + } + if (!exact) { + #ifdef TK_KANJI_OK + Tcl_DWStringSetLength(&line, Tcl_DWStringLength(&line)-1); + #else + Tcl_DStringSetLength(&line, Tcl_DStringLength(&line)-1); + #endif /* TK_KANJI_OK */ + } + #ifdef TK_KANJI_OK + startOfLine = Tcl_DWStringValue(&line); + #else + startOfLine = Tcl_DStringValue(&line); + #endif /* TK_KANJI_OK */ + + /* + * If we're ignoring case, convert the line to lower case. + */ + + if (noCase) { + #ifdef TK_KANJI_OK + for (p = Tcl_DWStringValue(&line); *p != 0; p++) { + if (ISWUPPER(*p)) { + *p = (wchar) tolower(UCHAR(*p)); + } + } + #else + for (p = Tcl_DStringValue(&line); *p != 0; p++) { + if (isupper(UCHAR(*p))) { + *p = tolower(UCHAR(*p)); + } + } + #endif /* TK_KANJI_OK */ + } + + /* + * Check for matches within the current line. If so, and if we're + * searching backwards, repeat the search to find the last match + * in the line. + */ + + matchChar = -1; + firstChar = 0; + lastChar = INT_MAX; + if (lineNum == startingLine) { + /* + * The starting line is tricky: the first time we see it + * we check one part of the line, and the second pass through + * we check the other part of the line. + */ + + passes++; + if (passes == 1) { + if (backwards) { + lastChar = startingChar; + } else { + firstChar = startingChar; + if (firstChar >= Tcl_DStringLength(&line)) { + goto nextLine; + } + } + } else { + if (backwards) { + firstChar = startingChar; + } else { + lastChar = startingChar; + } + } + } + do { + int thisLength; + if (exact) { + #ifdef TK_KANJI_OK + p = Tcl_WStrstr(startOfLine + firstChar, pattern); + #else + p = strstr(startOfLine + firstChar, pattern); + #endif /* TK_KANJI_OK */ + if (p == NULL) { + break; + } + i = p - startOfLine; + thisLength = patLength; + } else { + #ifdef TK_KANJI_OK + #else + char *start, *end; + int match; + + match = Tcl_RegExpExec(interp, regexp, + startOfLine + firstChar, startOfLine); + if (match < 0) { + code = TCL_ERROR; + goto done; + } + if (!match) { + break; + } + Tcl_RegExpRange(regexp, 0, &start, &end); + i = start - startOfLine; + thisLength = end - start; + #endif /* TK_KANJI_OK */ + } + if (i >= lastChar) { + break; + } + matchChar = i; + matchLength = thisLength; + firstChar = matchChar+1; + } while (backwards); + + /* + * If we found a match then we're done. Make sure that + * the match occurred before the stopping index, if one was + * specified. + */ + + if (matchChar >= 0) { + /* + * The index information returned by the regular expression + * parser only considers textual information: it doesn't + * account for embedded windows or any other non-textual info. + * Scan through the line's segments again to adjust both + * matchChar and matchCount. + */ + + for (segPtr = linePtr->segPtr, leftToScan = matchChar; + leftToScan >= 0; segPtr = segPtr->nextPtr) { + if (segPtr->typePtr != &tkTextCharType) { + matchChar += segPtr->size; + continue; + } + leftToScan -= segPtr->size; + } + for (leftToScan += matchLength; leftToScan > 0; + segPtr = segPtr->nextPtr) { + if (segPtr->typePtr != &tkTextCharType) { + matchLength += segPtr->size; + continue; + } + leftToScan -= segPtr->size; + } + TkTextMakeIndex(textPtr->tree, lineNum, matchChar, &index); + if (!searchWholeText) { + if (!backwards && (TkTextIndexCmp(&index, &stopIndex) >= 0)) { + goto done; + } + if (backwards && (TkTextIndexCmp(&index, &stopIndex) < 0)) { + goto done; + } + } + if (varName != NULL) { + sprintf(buffer, "%d", matchLength); + if (Tcl_SetVar(interp, varName, buffer, TCL_LEAVE_ERR_MSG) + == NULL) { + code = TCL_ERROR; + goto done; + } + } + TkTextPrintIndex(&index, interp->result); + goto done; + } + + /* + * Go to the next (or previous) line; + */ + + nextLine: + if (backwards) { + lineNum--; + if (!searchWholeText) { + if (lineNum < stopLine) { + break; + } + } else if (lineNum < 0) { + lineNum = numLines-1; + } + } else { + lineNum++; + if (!searchWholeText) { + if (lineNum > stopLine) { + break; + } + } else if (lineNum >= numLines) { + lineNum = 0; + } + } + #ifdef TK_KANJI_OK + Tcl_DWStringSetLength(&line, 0); + #else + Tcl_DStringSetLength(&line, 0); + #endif /* TK_KANJI_OK */ + } + done: + #ifdef TK_KANJI_OK + Tcl_DWStringFree(&line); + if (noCase) { + Tcl_DWStringFree(&patDString); + } + Tcl_FreeWStr(pPattern); + #else + Tcl_DStringFree(&line); + if (noCase) { + Tcl_DStringFree(&patDString); + } + #endif /* TK_KANJI_OK */ + return code; + } + #endif /* TK_KANJI_OK */ /* *---------------------------------------------------------------------- *************** *** 2167,2173 **** --- 2896,2908 ---- offset += segPtr->size, segPtr = segPtr->nextPtr) { if ((what & TK_DUMP_TEXT) && (segPtr->typePtr == &tkTextCharType) && (offset + segPtr->size > start)) { + #ifdef TK_KANJI_OK + wchar savedChar; /* Last char used in the seg */ + int kanjiCode = Tcl_KanjiCode(interp); + char *str; + #else char savedChar; /* Last char used in the seg */ + #endif /* TK_KANJI_OK */ int last = segPtr->size; /* Index of savedChar */ int first = 0; /* Index of first char in seg */ if (offset + segPtr->size > end) { *************** *** 2178,2185 **** --- 2913,2929 ---- } savedChar = segPtr->body.chars[last]; segPtr->body.chars[last] = '\0'; + #ifdef TK_KANJI_OK + str = (char *) ckalloc((unsigned) + (Tcl_KanjiDecode(kanjiCode, segPtr->body.chars + first, NULL) + 1)); + (void) Tcl_KanjiDecode(kanjiCode, segPtr->body.chars + first, str); + DumpSegment(interp, "text", str, + command, lineno, offset + first, what); + ckfree(str); + #else DumpSegment(interp, "text", segPtr->body.chars + first, command, lineno, offset + first, what); + #endif /* TK_KANJI_OK */ segPtr->body.chars[last] = savedChar; } else if ((offset >= start)) { if ((what & TK_DUMP_MARK) && (segPtr->typePtr->name[0] == 'm')) { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkText.h ./generic/tkText.h *** ../../tk8.0.5/generic/tkText.h Tue Sep 15 03:23:18 1998 --- ./generic/tkText.h Fri Mar 12 00:37:09 1999 *************** *** 16,21 **** --- 16,25 ---- #ifndef _TKTEXT #define _TKTEXT + #ifdef KANJI + #define TK_KANJI_OK + #endif + #ifndef _TK #include "tk.h" #endif *************** *** 151,159 **** --- 155,167 ---- int size; /* Size of this segment (# of bytes * of index space it occupies). */ union { + #ifdef TK_KANJI_OK + wchar chars[4]; + #else char chars[4]; /* Characters that make up character * info. Actual length varies to * hold as many characters as needed.*/ + #endif /* TK_KANJI_OK */ TkTextToggle toggle; /* Information about tag toggle. */ TkTextMark mark; /* Information about mark. */ TkTextEmbWindow ew; /* Information about embedded *************** *** 842,847 **** --- 850,859 ---- char *name, TkTextIndex *indexPtr)); extern int TkTextXviewCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int argc, char **argv)); + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + extern int TkTextXYPos _ANSI_ARGS_((Tcl_Interp *interp, + TkText *textPtr, TkTextIndex *indexPtr)); + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ extern int TkTextYviewCmd _ANSI_ARGS_((TkText *textPtr, Tcl_Interp *interp, int argc, char **argv)); diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkTextBTree.c ./generic/tkTextBTree.c *** ../../tk8.0.5/generic/tkTextBTree.c Tue Sep 15 03:23:18 1998 --- ./generic/tkTextBTree.c Fri Mar 12 00:37:10 1999 *************** *** 103,111 **** /* * Macros that determine how much space to allocate for new segments: */ ! #define CSEG_SIZE(chars) ((unsigned) (Tk_Offset(TkTextSegment, body) \ + 1 + (chars))) #define TSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \ + sizeof(TkTextToggle))) --- 103,115 ---- /* * Macros that determine how much space to allocate for new segments: */ ! #ifdef TK_KANJI_OK ! #define CSEG_SIZE(chars) ((unsigned) (Tk_Offset(TkTextSegment, body) \ ! + (1 + (chars)) * sizeof(wchar))) ! #else #define CSEG_SIZE(chars) ((unsigned) (Tk_Offset(TkTextSegment, body) \ + 1 + (chars))) + #endif /* TK_KANJI_OK */ #define TSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \ + sizeof(TkTextToggle))) *************** *** 410,419 **** --- 414,432 ---- register TkTextSegment *segPtr; TkTextLine *newLinePtr; int chunkSize; /* # characters in current chunk. */ + #ifdef TK_KANJI_OK + register wchar *eol; /* Pointer to character just after last + * one in current chunk. */ + #else register char *eol; /* Pointer to character just after last * one in current chunk. */ + #endif /* TK_KANJI_OK */ int changeToLineCount; /* Counts change to total number of * lines in file. */ + #ifdef TK_KANJI_OK + wchar *wstr = Tcl_GetWStr(NULL, string, NULL); + #define string wstr + #endif /* TK_KANJI_OK */ prevPtr = SplitSeg(indexPtr); linePtr = indexPtr->linePtr; *************** *** 444,450 **** --- 457,467 ---- curPtr->nextPtr = segPtr; } segPtr->size = chunkSize; + #ifdef TK_KANJI_OK + Tcl_WStrncpy(segPtr->body.chars, wstr, chunkSize); + #else strncpy(segPtr->body.chars, string, (size_t) chunkSize); + #endif /* TK_KANJI_OK */ segPtr->body.chars[chunkSize] = 0; if (eol[-1] != '\n') { *************** *** 497,502 **** --- 514,522 ---- if (tkBTreeDebug) { TkBTreeCheck(indexPtr->tree); } + #ifdef TK_KANJI_OK + #undef string + #endif /* TK_KANJI_OK */ } /* *************** *** 3232,3243 **** --- 3252,3271 ---- newPtr1->typePtr = &tkTextCharType; newPtr1->nextPtr = newPtr2; newPtr1->size = index; + #ifdef TK_KANJI_OK + Tcl_WStrncpy(newPtr1->body.chars, segPtr->body.chars, index); + #else strncpy(newPtr1->body.chars, segPtr->body.chars, (size_t) index); + #endif /* TK_KANJI_OK */ newPtr1->body.chars[index] = 0; newPtr2->typePtr = &tkTextCharType; newPtr2->nextPtr = segPtr->nextPtr; newPtr2->size = segPtr->size - index; + #ifdef TK_KANJI_OK + Tcl_WStrcpy(newPtr2->body.chars, segPtr->body.chars + index); + #else strcpy(newPtr2->body.chars, segPtr->body.chars + index); + #endif /* TK_KANJI_OK */ ckfree((char*) segPtr); return newPtr1; } *************** *** 3279,3286 **** --- 3307,3319 ---- newPtr->typePtr = &tkTextCharType; newPtr->nextPtr = segPtr2->nextPtr; newPtr->size = segPtr->size + segPtr2->size; + #ifdef TK_KANJI_OK + Tcl_WStrcpy(newPtr->body.chars, segPtr->body.chars); + Tcl_WStrcpy(newPtr->body.chars + segPtr->size, segPtr2->body.chars); + #else strcpy(newPtr->body.chars, segPtr->body.chars); strcpy(newPtr->body.chars + segPtr->size, segPtr2->body.chars); + #endif /* TK_KANJI_OK */ ckfree((char*) segPtr); ckfree((char*) segPtr2); return newPtr; *************** *** 3350,3356 **** --- 3383,3393 ---- if (segPtr->size <= 0) { panic("CharCheckProc: segment has size <= 0"); } + #ifdef TK_KANJI_OK + if (Tcl_WStrlen(segPtr->body.chars) != segPtr->size) { + #else if (strlen(segPtr->body.chars) != (size_t) segPtr->size) { + #endif /* TK_KANJI_OK */ panic("CharCheckProc: segment has wrong size"); } if (segPtr->nextPtr == NULL) { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkTextDisp.c ./generic/tkTextDisp.c *** ../../tk8.0.5/generic/tkTextDisp.c Tue Sep 15 03:23:18 1998 --- ./generic/tkTextDisp.c Fri Mar 12 00:37:11 1999 *************** *** 11,19 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkTextDisp.c,v 1.2 1998/09/14 18:23:18 stanton Exp $ */ #include "tkPort.h" #include "tkInt.h" #include "tkText.h" --- 11,23 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkTextDisp.c,v 1.10 1999/03/11 15:37:11 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif + #include "tkPort.h" #include "tkInt.h" #include "tkText.h" *************** *** 255,263 **** --- 259,273 ---- typedef struct CharInfo { int numChars; /* Number of characters to display. */ + #ifdef TK_KANJI_OK + wchar chars[4]; /* Characters to display. Actual size + * will be numChars, not 4. THIS MUST BE + * THE LAST FIELD IN THE STRUCTURE. */ + #else char chars[4]; /* Characters to display. Actual size * will be numChars, not 4. THIS MUST BE * THE LAST FIELD IN THE STRUCTURE. */ + #endif /* TK_KANJI_OK */ } CharInfo; /* *************** *** 330,338 **** --- 340,354 ---- TkText *textPtr, int report)); static DLine * LayoutDLine _ANSI_ARGS_((TkText *textPtr, TkTextIndex *indexPtr)); + #ifdef TK_KANJI_OK + static int MeasureChars _ANSI_ARGS_((Tk_Font tkfont, + CONST wchar *source, int maxChars, int startX, + int maxX, int tabOrigin, int *nextXPtr)); + #else static int MeasureChars _ANSI_ARGS_((Tk_Font tkfont, CONST char *source, int maxChars, int startX, int maxX, int tabOrigin, int *nextXPtr)); + #endif /* TK_KANJI_OK */ static void MeasureUp _ANSI_ARGS_((TkText *textPtr, TkTextIndex *srcPtr, int distance, TkTextIndex *dstPtr)); *************** *** 866,873 **** maxChars = segPtr->size - offset; if (justify == TK_JUSTIFY_LEFT) { if (segPtr->typePtr == &tkTextCharType) { char *p; ! for (p = segPtr->body.chars + offset; *p != 0; p++) { if (*p == '\t') { maxChars = (p + 1 - segPtr->body.chars) - offset; --- 882,892 ---- maxChars = segPtr->size - offset; if (justify == TK_JUSTIFY_LEFT) { if (segPtr->typePtr == &tkTextCharType) { + #ifdef TK_KANJI_OK + wchar *p; + #else char *p; ! #endif /* TK_KANJI_OK */ for (p = segPtr->body.chars + offset; *p != 0; p++) { if (*p == '\t') { maxChars = (p + 1 - segPtr->body.chars) - offset; *************** *** 4244,4250 **** --- 4263,4274 ---- Tk_Font tkfont; int nextX, charsThatFit, count; CharInfo *ciPtr; + #ifdef TK_KANJI_OK + wchar *p; + wchar nextC; + #else char *p; + #endif /* TK_KANJI_OK */ TkTextSegment *nextPtr; Tk_FontMetrics fm; *************** *** 4311,4321 **** --- 4335,4354 ---- chunkPtr->minHeight = 0; chunkPtr->width = nextX - chunkPtr->x; chunkPtr->breakIndex = -1; + #ifdef TK_KANJI_OK + ciPtr = (CharInfo *) ckalloc((unsigned) + (sizeof(CharInfo) + (charsThatFit - 3) * sizeof(wchar))); + #else ciPtr = (CharInfo *) ckalloc((unsigned) (sizeof(CharInfo) - 3 + charsThatFit)); + #endif /* TK_KANJI_OK */ chunkPtr->clientData = (ClientData) ciPtr; ciPtr->numChars = charsThatFit; + #ifdef TK_KANJI_OK + Tcl_WStrncpy(ciPtr->chars, p, charsThatFit); + #else strncpy(ciPtr->chars, p, (size_t) charsThatFit); + #endif /* TK_KANJI_OK */ if (p[charsThatFit-1] == '\n') { ciPtr->numChars--; } *************** *** 4330,4341 **** --- 4363,4400 ---- if (wrapMode != tkTextWordUid) { chunkPtr->breakIndex = chunkPtr->numChars; } else { + #ifdef TK_KANJI_OK + if ((charsThatFit + offset) == segPtr->size) { + for (nextPtr = segPtr->nextPtr; nextPtr != NULL; + nextPtr = nextPtr->nextPtr) { + if (nextPtr->typePtr == &tkTextCharType && + nextPtr->size != 0) { + break; + } + } + if (nextPtr == NULL) { + goto nextTextNotFound; + } else { + nextC = nextPtr->body.chars[0]; + } + } else { + nextTextNotFound: + nextC = p[charsThatFit]; + } + #endif /* TK_KANJI_OK */ for (count = charsThatFit, p += charsThatFit-1; count > 0; count--, p--) { + #ifdef TK_KANJI_OK + if (TkpIsBreakablePoint(*p, nextC)) { + #else if (isspace(UCHAR(*p))) { + #endif /* TK_KANJI_OK */ chunkPtr->breakIndex = count; break; } + #ifdef TK_KANJI_OK + nextC = *p; + #endif /* TK_KANJI_OK */ } if ((charsThatFit+offset) == segPtr->size) { for (nextPtr = segPtr->nextPtr; nextPtr != NULL; *************** *** 4423,4430 **** if (ciPtr->numChars > offsetChars) { int numChars = ciPtr->numChars - offsetChars; char *string = ciPtr->chars + offsetChars; ! if ((numChars > 0) && (string[numChars - 1] == '\t')) { numChars--; } --- 4482,4492 ---- if (ciPtr->numChars > offsetChars) { int numChars = ciPtr->numChars - offsetChars; + #ifdef TK_KANJI_OK + wchar *string = ciPtr->chars + offsetChars; + #else char *string = ciPtr->chars + offsetChars; ! #endif /* TK_KANJI_ OK */ if ((numChars > 0) && (string[numChars - 1] == '\t')) { numChars--; } *************** *** 4628,4634 **** --- 4690,4700 ---- TkTextDispChunk *chunkPtr2, *decimalChunkPtr; CharInfo *ciPtr; int tabX, prev, spaceWidth; + #ifdef TK_KANJI_OK + wchar *p; + #else char *p; + #endif /* TK_KANJI_OK */ TkTextTabAlign alignment; if (chunkPtr->nextPtr == NULL) { *************** *** 4714,4720 **** --- 4780,4790 ---- } ciPtr = (CharInfo *) chunkPtr2->clientData; for (p = ciPtr->chars, i = 0; i < ciPtr->numChars; p++, i++) { + #ifdef TK_KANJI_OK + if (ISWDIGIT(*p)) { + #else if (isdigit(UCHAR(*p))) { + #endif /* TK_KANJI_OK */ gotDigit = 1; } else if ((*p == '.') || (*p == ',')) { decimal = p-ciPtr->chars; *************** *** 4759,4765 **** --- 4829,4842 ---- update: delta = desired - x; + #ifdef TK_KANJI_OK + { + wchar wTmp = ' '; + MeasureChars(textPtr->tkfont, &wTmp, 1, 0, INT_MAX, 0, &spaceWidth); + } + #else MeasureChars(textPtr->tkfont, " ", 1, 0, INT_MAX, 0, &spaceWidth); + #endif if (delta < spaceWidth) { delta = spaceWidth; } *************** *** 4864,4870 **** --- 4941,4954 ---- } done: + #ifdef TK_KANJI_OK + { + wchar wTmp = ' '; + MeasureChars(textPtr->tkfont, &wTmp, 1, 0, INT_MAX, 0, &spaceWidth); + } + #else MeasureChars(textPtr->tkfont, " ", 1, 0, INT_MAX, 0, &spaceWidth); + #endif /* TK_KANJI_OK */ if (result < spaceWidth) { result = spaceWidth; } *************** *** 4901,4908 **** * non-zero if text has been scrolled. */ { int tabWidth, rem; ! tabWidth = Tk_TextWidth(tkfont, "0", 1) * 8; if (tabWidth == 0) { tabWidth = 1; } --- 4985,4997 ---- * non-zero if text has been scrolled. */ { int tabWidth, rem; ! ! #ifdef TK_KANJI_OK ! wchar wTmp = '0'; ! tabWidth = Tk_TextWidth(tkfont, &wTmp, 1) * 8; ! #else tabWidth = Tk_TextWidth(tkfont, "0", 1) * 8; + #endif /* TK_KANJI_OK */ if (tabWidth == 0) { tabWidth = 1; } *************** *** 4949,4956 **** --- 5038,5050 ---- static int MeasureChars(tkfont, source, maxChars, startX, maxX, tabOrigin, nextXPtr) Tk_Font tkfont; /* Font in which to draw characters. */ + #ifdef TK_KANJI_OK + CONST wchar *source; /* Characters to be displayed. Need not + * be NULL-terminated. */ + #else CONST char *source; /* Characters to be displayed. Need not * be NULL-terminated. */ + #endif /* TK_KANJI_OK */ int maxChars; /* Maximum # of characters to consider from * source. */ int startX; /* X-position at which first character will *************** *** 4963,4970 **** * character here. */ { int curX, width, ch; CONST char *special, *end, *start; ! ch = 0; /* lint. */ curX = startX; special = source; --- 5057,5067 ---- * character here. */ { int curX, width, ch; + #ifdef TK_KANJI_OK + CONST wchar *special, *end, *start; + #else CONST char *special, *end, *start; ! #endif /* TK_KANJI_OK */ ch = 0; /* lint. */ curX = startX; special = source; *************** *** 5013,5015 **** --- 5110,5172 ---- *nextXPtr = curX; return start - source; } + #if defined(KINPUT2) || defined(XIM_IMPROVE) || defined(IME_AWARE) + /* + *-------------------------------------------------------------- + * + * TkTextXYPos -- + * + * This procedure returns XY coordinates of the point + * specified by its line and character index. + * The Y coordinate is of the baseline of the line + * on which the point is. + * + * Results: + * The return value is always TCL_OK (i.e. no errors possible). + * If the point is visible, this procedure will return a list + * containing its X and Y position. Othewise, an empty string + * will be returned. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + int + TkTextXYPos(interp, textPtr, indexPtr) + Tcl_Interp *interp; /* For the result */ + TkText *textPtr; /* Text for which the index is being + * specified. */ + TkTextIndex *indexPtr; /* Character index for which its position + * is to be retrieved. */ + { + register TkTextDispChunk *chunkPtr; + TextDInfo *dInfoPtr = textPtr->dInfoPtr; + DLine *dlPtr; + int x, y; + + /* + * Make sure that all of the layout information about what's + * displayed where on the screen is up-to-date. + */ + if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { + UpdateDisplayInfo(textPtr); + } + + dlPtr = FindDLine(dInfoPtr->dLinePtr, indexPtr); + if (dlPtr == NULL) return TCL_OK; + + for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL); + chunkPtr = chunkPtr->nextPtr) { + if (chunkPtr->displayProc == TkTextInsertDisplayProc) { + x = chunkPtr->x + dInfoPtr->x - dInfoPtr->curPixelOffset; + y = dlPtr->y + dlPtr->baseline; + sprintf(interp->result, "%d %d", x, y); + return TCL_OK; + } + } + + return TCL_OK; + } + #endif /* KINPUT2 || XIM_IMPROVE || IME_AWARE */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkTextIndex.c ./generic/tkTextIndex.c *** ../../tk8.0.5/generic/tkTextIndex.c Tue Sep 15 03:23:19 1998 --- ./generic/tkTextIndex.c Fri Mar 12 00:37:12 1999 *************** *** 748,754 **** --- 748,759 ---- TkTextIndex *indexPtr; /* Index to mdoify based on string. */ { char *p; + #ifdef TK_KANJI_OK + wchar c; + int offset; + #else int c, offset; + #endif /* TK_KANJI_OK */ size_t length; register TkTextSegment *segPtr; *************** *** 785,791 **** --- 790,800 ---- while (1) { if (segPtr->typePtr == &tkTextCharType) { c = segPtr->body.chars[offset]; + #ifdef TK_KANJI_OK + if (!ISWALNUM(c) && (c != '_')) { + #else if (!isalnum(UCHAR(c)) && (c != '_')) { + #endif /* TK_KANJI_OK */ break; } firstChar = 0; *************** *** 814,820 **** --- 823,833 ---- while (1) { if (segPtr->typePtr == &tkTextCharType) { c = segPtr->body.chars[offset]; + #ifdef TK_KANJI_OK + if (!ISWALNUM(c) && (c != '_')) { + #else if (!isalnum(UCHAR(c)) && (c != '_')) { + #endif /* TK_KANJI_OK */ break; } firstChar = 0; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkWFont.c ./generic/tkWFont.c *** ../../tk8.0.5/generic/tkWFont.c Thu Jan 1 09:00:00 1970 --- ./generic/tkWFont.c Wed Feb 10 19:48:34 1999 *************** *** 0 **** --- 1,1251 ---- + /* + * tkWFont.c -- + * + * This file has definitions for wide string measuring/displaying + * text functions in tkFont.c + */ + + #ifdef KANJI + + #include "tkInt.h" + #include "tkFont.h" + + typedef struct WLayoutChunk { + CONST wchar *start; /* Pointer to simple string to be displayed. + * This is a pointer into the TkWTextLayout's + * string. */ + int numChars; /* The number of characters in this chunk. */ + int numDisplayChars; /* The number of characters to display when + * this chunk is displayed. Can be less than + * numChars if extra space characters were + * absorbed by the end of the chunk. This + * will be < 0 if this is a chunk that is + * holding a tab or newline. */ + int x, y; /* The origin of the first character in this + * chunk with respect to the upper-left hand + * corner of the WTextLayout. */ + int totalWidth; /* Width in pixels of this chunk. Used + * when hit testing the invisible spaces at + * the end of a chunk. */ + int displayWidth; /* Width in pixels of the displayable + * characters in this chunk. Can be less than + * width if extra space characters were + * absorbed by the end of the chunk. */ + } WLayoutChunk; + + typedef struct WTextLayout { + Tk_Font tkfont; /* The font used when laying out the text. */ + CONST wchar *string; /* The string that was layed out. */ + int width; /* The maximum width of all lines in the + * text layout. */ + int numChunks; /* Number of chunks actually used in + * following array. */ + WLayoutChunk chunks[1]; /* Array of chunks. The actual size will + * be maxChunks. THIS FIELD MUST BE THE LAST + * IN THE STRUCTURE. */ + } WTextLayout; + + static WLayoutChunk * NewWChunk _ANSI_ARGS_((WTextLayout **layoutPtrPtr, + int *maxPtr, CONST wchar *start, int numChars, + int curX, int newX, int y)); + + + /* + *--------------------------------------------------------------------------- + * + * Tk_WTextWidth -- + * + * A wrapper function for the more complicated interface of + * Tk_MeasureChars. Computes how much space the given + * simple string needs. + * + * Results: + * The return value is the width (in pixels) of the given string. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + Tk_WTextWidth(tkfont, string, numChars) + Tk_Font tkfont; /* Font in which text will be measured. */ + CONST wchar *string; /* String whose width will be computed. */ + int numChars; /* Number of characters to consider from + * string, or < 0 for Tcl_WStrlen(). */ + { + int width; + + if (numChars < 0) { + numChars = Tcl_WStrlen((wchar *)string); + } + Tk_MeasureWChars(tkfont, string, numChars, 0, 0, &width); + return width; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_UnderlineWChars -- + * + * This procedure draws an underline for a given range of characters + * in a given string. It doesn't draw the characters (which are + * assumed to have been displayed previously); it just draws the + * underline. This procedure would mainly be used to quickly + * underline a few characters without having to construct an + * underlined font. To produce properly underlined text, the + * appropriate underlined font should be constructed and used. + * + * Results: + * None. + * + * Side effects: + * Information gets displayed in "drawable". + * + *---------------------------------------------------------------------- + */ + + void + Tk_UnderlineWChars(display, drawable, gc, tkfont, string, x, y, firstChar, + lastChar) + Display *display; /* Display on which to draw. */ + Drawable drawable; /* Window or pixmap in which to draw. */ + GC gc; /* Graphics context for actually drawing + * line. */ + Tk_Font tkfont; /* Font used in GC; must have been allocated + * by Tk_GetFont(). Used for character + * dimensions, etc. */ + CONST wchar *string; /* String containing characters to be + * underlined or overstruck. */ + int x, y; /* Coordinates at which first character of + * string is drawn. */ + int firstChar; /* Index of first character. */ + int lastChar; /* Index of one after the last character. */ + { + TkFont *fontPtr; + int startX, endX; + + fontPtr = (TkFont *) tkfont; + + Tk_MeasureWChars(tkfont, string, firstChar, 0, 0, &startX); + Tk_MeasureWChars(tkfont, string, lastChar, 0, 0, &endX); + + XFillRectangle(display, drawable, gc, x + startX, + y + fontPtr->underlinePos, (unsigned int) (endX - startX), + (unsigned int) fontPtr->underlineHeight); + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_ComputeWTextLayout -- + * + * Computes the amount of screen space needed to display a + * multi-line, justified string of text. Records all the + * measurements that were done to determine to size and + * positioning of the individual lines of text; this information + * can be used by the Tk_DrawWTextLayout() procedure to + * display the text quickly (without remeasuring it). + * + * This procedure is useful for simple widgets that want to + * display single-font, multi-line text and want Tk to handle the + * details. + * + * Results: + * The return value is a Tk_TextLayout token that holds the + * measurement information for the given string. The token is + * only valid for the given string. If the string is freed, + * the token is no longer valid and must also be freed. To free + * the token, call Tk_FreeWTextLayout(). + * + * The dimensions of the screen area needed to display the text + * are stored in *widthPtr and *heightPtr. + * + * Side effects: + * Memory is allocated to hold the measurement information. + * + *--------------------------------------------------------------------------- + */ + + Tk_WTextLayout + Tk_ComputeWTextLayout(tkfont, string, numChars, wrapLength, justify, flags, + widthPtr, heightPtr) + Tk_Font tkfont; /* Font that will be used to display text. */ + CONST wchar *string; /* String whose dimensions are to be + * computed. */ + int numChars; /* Number of characters to consider from + * string, or < 0 for Tcl_WStrlen(). */ + int wrapLength; /* Longest permissible line length, in + * pixels. <= 0 means no automatic wrapping: + * just let lines get as long as needed. */ + Tk_Justify justify; /* How to justify lines. */ + int flags; /* Flag bits OR-ed together. + * TK_IGNORE_TABS means that tab characters + * should not be expanded. TK_IGNORE_NEWLINES + * means that newline characters should not + * cause a line break. */ + int *widthPtr; /* Filled with width of string. */ + int *heightPtr; /* Filled with height of string. */ + { + TkFont *fontPtr; + CONST wchar *start, *end, *special; + int n, y, charsThisChunk, maxChunks; + int baseline, height, curX, newX, maxWidth; + WTextLayout *layoutPtr; + WLayoutChunk *chunkPtr; + CONST TkFontMetrics *fmPtr; + #define MAX_LINES 50 + int staticLineLengths[MAX_LINES]; + int *lineLengths; + int maxLines, curLine, layoutHeight; + + lineLengths = staticLineLengths; + maxLines = MAX_LINES; + #ifdef BUGFIX + /* + * XXX + */ + memset((VOID *)staticLineLengths, 0, sizeof(int) * MAX_LINES); + #endif /* BUGFIX */ + + fontPtr = (TkFont *) tkfont; + fmPtr = &fontPtr->fm; + + height = fmPtr->ascent + fmPtr->descent; + + if (numChars < 0) { + numChars = Tcl_WStrlen((wchar *)string); + } + + maxChunks = 1; + + layoutPtr = (WTextLayout *) ckalloc(sizeof(WTextLayout) + + (maxChunks - 1) * sizeof(WLayoutChunk)); + layoutPtr->tkfont = tkfont; + layoutPtr->string = string; + layoutPtr->numChunks = 0; + + baseline = fmPtr->ascent; + maxWidth = 0; + + /* + * Divide the string up into simple strings and measure each string. + */ + + curX = 0; + + end = string + numChars; + special = string; + + flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES; + flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE; + curLine = 0; + for (start = string; start < end; ) { + if (start >= special) { + /* + * Find the next special character in the string. + */ + + for (special = start; special < end; special++) { + if (!(flags & TK_IGNORE_NEWLINES)) { + if ((*special == '\n') || (*special == '\r')) { + break; + } + } + if (!(flags & TK_IGNORE_TABS)) { + if (*special == '\t') { + break; + } + } + } + } + + /* + * Special points at the next special character (or the end of the + * string). Process characters between start and special. + */ + + chunkPtr = NULL; + if (start < special) { + charsThisChunk = Tk_MeasureWChars(tkfont, start, special - start, + wrapLength - curX, flags, &newX); + newX += curX; + flags &= ~TK_AT_LEAST_ONE; + if (charsThisChunk > 0) { + chunkPtr = NewWChunk(&layoutPtr, &maxChunks, start, + charsThisChunk, curX, newX, baseline); + + start += charsThisChunk; + curX = newX; + } + } + + if ((start == special) && (special < end)) { + /* + * Handle the special character. + */ + + chunkPtr = NULL; + if (*special == '\t') { + newX = curX + fontPtr->tabWidth; + newX -= newX % fontPtr->tabWidth; + NewWChunk(&layoutPtr, &maxChunks, start, 1, curX, newX, + baseline)->numDisplayChars = -1; + start++; + if ((start < end) && + ((wrapLength <= 0) || (newX <= wrapLength))) { + /* + * More chars can still fit on this line. + */ + + curX = newX; + flags &= ~TK_AT_LEAST_ONE; + continue; + } + } else { + NewWChunk(&layoutPtr, &maxChunks, start, 1, curX, 1000000000, + baseline)->numDisplayChars = -1; + start++; + goto wrapLine; + } + } + + /* + * No more characters are going to go on this line, either because + * no more characters can fit or there are no more characters left. + * Consume all extra spaces at end of line. + */ + + while ((start < end) && isspace(UCHAR(*start))) { + if (!(flags & TK_IGNORE_NEWLINES)) { + if ((*start == '\n') || (*start == '\r')) { + break; + } + } + if (!(flags & TK_IGNORE_TABS)) { + if (*start == '\t') { + break; + } + } + start++; + } + if (chunkPtr != NULL) { + /* + * Append all the extra spaces on this line to the end of the + * last text chunk. + */ + charsThisChunk = start - (chunkPtr->start + chunkPtr->numChars); + if (charsThisChunk > 0) { + chunkPtr->numChars += Tk_MeasureWChars(tkfont, + chunkPtr->start + chunkPtr->numChars, charsThisChunk, + 0, 0, &chunkPtr->totalWidth); + chunkPtr->totalWidth += curX; + } + } + + wrapLine: + flags |= TK_AT_LEAST_ONE; + + /* + * Save current line length, then move current position to start of + * next line. + */ + + if (curX > maxWidth) { + maxWidth = curX; + } + + /* + * Remember width of this line, so that all chunks on this line + * can be centered or right justified, if necessary. + */ + + if (curLine >= maxLines) { + int *newLengths; + + newLengths = (int *) ckalloc(2 * maxLines * sizeof(int)); + #ifdef BUGFIX + /* + * XXX + */ + memset((VOID *)newLengths, 0, 2 * maxLines * sizeof(int)); + #endif /* BUGFIX */ + memcpy((void *) newLengths, lineLengths, maxLines * sizeof(int)); + if (lineLengths != staticLineLengths) { + ckfree((char *) lineLengths); + } + lineLengths = newLengths; + maxLines *= 2; + } + lineLengths[curLine] = curX; + curLine++; + + curX = 0; + baseline += height; + } + + /* + * If last line ends with a newline, then we need to make a 0 width + * chunk on the next line. Otherwise "Hello" and "Hello\n" are the + * same height. + */ + + if ((layoutPtr->numChunks > 0) && ((flags & TK_IGNORE_NEWLINES) == 0)) { + if (layoutPtr->chunks[layoutPtr->numChunks - 1].start[0] == '\n') { + chunkPtr = NewWChunk(&layoutPtr, &maxChunks, start, 0, curX, + 1000000000, baseline); + chunkPtr->numDisplayChars = -1; + baseline += height; + } + } + + /* + * Using maximum line length, shift all the chunks so that the lines are + * all justified correctly. + */ + + curLine = 0; + chunkPtr = layoutPtr->chunks; + y = chunkPtr->y; + for (n = 0; n < layoutPtr->numChunks; n++) { + #ifdef BUGFIX + int extra = 0; + #else + int extra; + #endif /* BUGFIX */ + + if (chunkPtr->y != y) { + curLine++; + y = chunkPtr->y; + } + #ifdef BUGFIX + /* + * curLine could be out of range. lineLengths[curLine] must be + * initialized by zero in such a case. + */ + #endif /* BUGFIX */ + extra = maxWidth - lineLengths[curLine]; + if (justify == TK_JUSTIFY_CENTER) { + chunkPtr->x += extra / 2; + } else if (justify == TK_JUSTIFY_RIGHT) { + chunkPtr->x += extra; + } + chunkPtr++; + } + + layoutPtr->width = maxWidth; + layoutHeight = baseline - fmPtr->ascent; + if (layoutPtr->numChunks == 0) { + layoutHeight = height; + + /* + * This fake chunk is used by the other procedures so that they can + * pretend that there is a chunk with no chars in it, which makes + * the coding simpler. + */ + + layoutPtr->numChunks = 1; + layoutPtr->chunks[0].start = string; + layoutPtr->chunks[0].numChars = 0; + layoutPtr->chunks[0].numDisplayChars = -1; + layoutPtr->chunks[0].x = 0; + layoutPtr->chunks[0].y = fmPtr->ascent; + layoutPtr->chunks[0].totalWidth = 0; + layoutPtr->chunks[0].displayWidth = 0; + } + + if (widthPtr != NULL) { + *widthPtr = layoutPtr->width; + } + if (heightPtr != NULL) { + *heightPtr = layoutHeight; + } + if (lineLengths != staticLineLengths) { + ckfree((char *) lineLengths); + } + + return (Tk_WTextLayout) layoutPtr; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_FreeWTextLayout -- + * + * This procedure is called to release the storage associated with + * a Tk_WTextLayout when it is no longer needed. + * + * Results: + * None. + * + * Side effects: + * Memory is freed. + * + *--------------------------------------------------------------------------- + */ + + void + Tk_FreeWTextLayout(textLayout) + Tk_WTextLayout textLayout; /* The text layout to be released. */ + { + WTextLayout *layoutPtr; + + layoutPtr = (WTextLayout *) textLayout; + if (layoutPtr != NULL) { + ckfree((char *) layoutPtr); + } + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_DrawWTextLayout -- + * + * Use the information in the Tk_WTextLayout token to display a + * multi-line, justified string of text. + * + * This procedure is useful for simple widgets that need to + * display single-font, multi-line text and want Tk to handle + * the details. + * + * Results: + * None. + * + * Side effects: + * Text drawn on the screen. + * + *--------------------------------------------------------------------------- + */ + + void + Tk_DrawWTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) + Display *display; /* Display on which to draw. */ + Drawable drawable; /* Window or pixmap in which to draw. */ + GC gc; /* Graphics context to use for drawing text. */ + Tk_WTextLayout layout; /* Layout information, from a previous call + * to Tk_ComputeWTextLayout(). */ + int x, y; /* Upper-left hand corner of rectangle in + * which to draw (pixels). */ + int firstChar; /* The index of the first character to draw + * from the given text item. 0 specfies the + * beginning. */ + int lastChar; /* The index just after the last character + * to draw from the given text item. A number + * < 0 means to draw all characters. */ + { + WTextLayout *layoutPtr; + int i, numDisplayChars, drawX; + WLayoutChunk *chunkPtr; + + layoutPtr = (WTextLayout *) layout; + if (layoutPtr == NULL) { + return; + } + + if (lastChar < 0) { + lastChar = 100000000; + } + chunkPtr = layoutPtr->chunks; + for (i = 0; i < layoutPtr->numChunks; i++) { + numDisplayChars = chunkPtr->numDisplayChars; + if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) { + if (firstChar <= 0) { + drawX = 0; + firstChar = 0; + } else { + Tk_MeasureWChars(layoutPtr->tkfont, chunkPtr->start, firstChar, + 0, 0, &drawX); + } + if (lastChar < numDisplayChars) { + numDisplayChars = lastChar; + } + Tk_DrawWChars(display, drawable, gc, layoutPtr->tkfont, + chunkPtr->start + firstChar, numDisplayChars - firstChar, + x + chunkPtr->x + drawX, y + chunkPtr->y); + } + firstChar -= chunkPtr->numChars; + lastChar -= chunkPtr->numChars; + if (lastChar <= 0) { + break; + } + chunkPtr++; + } + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_UnderlineWTextLayout -- + * + * Use the information in the Tk_WTextLayout token to display an + * underline below an individual character. This procedure does + * not draw the text, just the underline. + * + * This procedure is useful for simple widgets that need to + * display single-font, multi-line text with an individual + * character underlined and want Tk to handle the details. + * To display larger amounts of underlined text, construct + * and use an underlined font. + * + * Results: + * None. + * + * Side effects: + * Underline drawn on the screen. + * + *--------------------------------------------------------------------------- + */ + + void + Tk_UnderlineWTextLayout(display, drawable, gc, layout, x, y, underline) + Display *display; /* Display on which to draw. */ + Drawable drawable; /* Window or pixmap in which to draw. */ + GC gc; /* Graphics context to use for drawing text. */ + Tk_WTextLayout layout; /* Layout information, from a previous call + * to Tk_ComputeWTextLayout(). */ + int x, y; /* Upper-left hand corner of rectangle in + * which to draw (pixels). */ + int underline; /* Index of the single character to + * underline, or -1 for no underline. */ + { + WTextLayout *layoutPtr; + TkFont *fontPtr; + int xx, yy, width, height; + + if ((Tk_WCharBbox(layout, underline, &xx, &yy, &width, &height) != 0) + && (width != 0)) { + layoutPtr = (WTextLayout *) layout; + fontPtr = (TkFont *) layoutPtr->tkfont; + + XFillRectangle(display, drawable, gc, x + xx, + y + yy + fontPtr->fm.ascent + fontPtr->underlinePos, + (unsigned int) width, (unsigned int) fontPtr->underlineHeight); + } + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_PointToWChar -- + * + * Use the information in the Tk_WTextLayout token to determine the + * character closest to the given point. The point must be + * specified with respect to the upper-left hand corner of the + * text layout, which is considered to be located at (0, 0). + * + * Any point whose y-value is less that 0 will be considered closest + * to the first character in the text layout; any point whose y-value + * is greater than the height of the text layout will be considered + * closest to the last character in the text layout. + * + * Any point whose x-value is less than 0 will be considered closest + * to the first character on that line; any point whose x-value is + * greater than the width of the text layout will be considered + * closest to the last character on that line. + * + * Results: + * The return value is the index of the character that was + * closest to the point. Given a text layout with no characters, + * the value 0 will always be returned, referring to a hypothetical + * zero-width placeholder character. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + Tk_PointToWChar(layout, x, y) + Tk_WTextLayout layout; /* Layout information, from a previous call + * to Tk_ComputeWTextLayout(). */ + int x, y; /* Coordinates of point to check, with + * respect to the upper-left corner of the + * text layout. */ + { + WTextLayout *layoutPtr; + WLayoutChunk *chunkPtr, *lastPtr; + TkFont *fontPtr; + int i, n, dummy, baseline, pos; + + if (y < 0) { + /* + * Point lies above any line in this layout. Return the index of + * the first char. + */ + + return 0; + } + + /* + * Find which line contains the point. + */ + + layoutPtr = (WTextLayout *) layout; + fontPtr = (TkFont *) layoutPtr->tkfont; + lastPtr = chunkPtr = layoutPtr->chunks; + for (i = 0; i < layoutPtr->numChunks; i++) { + baseline = chunkPtr->y; + if (y < baseline + fontPtr->fm.descent) { + if (x < chunkPtr->x) { + /* + * Point is to the left of all chunks on this line. Return + * the index of the first character on this line. + */ + + return chunkPtr->start - layoutPtr->string; + } + if (x >= layoutPtr->width) { + /* + * If point lies off right side of the text layout, return + * the last char in the last chunk on this line. Without + * this, it might return the index of the first char that + * was located outside of the text layout. + */ + + x = INT_MAX; + } + + /* + * Examine all chunks on this line to see which one contains + * the specified point. + */ + + lastPtr = chunkPtr; + while ((i < layoutPtr->numChunks) && (chunkPtr->y == baseline)) { + if (x < chunkPtr->x + chunkPtr->totalWidth) { + /* + * Point falls on one of the characters in this chunk. + */ + + if (chunkPtr->numDisplayChars < 0) { + /* + * This is a special chunk that encapsulates a single + * tab or newline char. + */ + + return chunkPtr->start - layoutPtr->string; + } + n = Tk_MeasureWChars((Tk_Font) fontPtr, chunkPtr->start, + chunkPtr->numChars, x + 1 - chunkPtr->x, + TK_PARTIAL_OK, &dummy); + return (chunkPtr->start + n - 1) - layoutPtr->string; + } + lastPtr = chunkPtr; + chunkPtr++; + i++; + } + + /* + * Point is to the right of all chars in all the chunks on this + * line. Return the index just past the last char in the last + * chunk on this line. + */ + + pos = (lastPtr->start + lastPtr->numChars) - layoutPtr->string; + if (i < layoutPtr->numChunks) { + pos--; + } + return pos; + } + lastPtr = chunkPtr; + chunkPtr++; + } + + /* + * Point lies below any line in this text layout. Return the index + * just past the last char. + */ + + return (lastPtr->start + lastPtr->numChars) - layoutPtr->string; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_WCharBbox -- + * + * Use the information in the Tk_WTextLayout token to return the + * bounding box for the character specified by index. + * + * The width of the bounding box is the advance width of the + * character, and does not include and left- or right-bearing. + * Any character that extends partially outside of the + * text layout is considered to be truncated at the edge. Any + * character which is located completely outside of the text + * layout is considered to be zero-width and pegged against + * the edge. + * + * The height of the bounding box is the line height for this font, + * extending from the top of the ascent to the bottom of the + * descent. Information about the actual height of the individual + * letter is not available. + * + * A text layout that contains no characters is considered to + * contain a single zero-width placeholder character. + * + * Results: + * The return value is 0 if the index did not specify a character + * in the text layout, or non-zero otherwise. In that case, + * *bbox is filled with the bounding box of the character. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + Tk_WCharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) + Tk_WTextLayout layout; /* Layout information, from a previous call to + * Tk_ComputeWTextLayout(). */ + int index; /* The index of the character whose bbox is + * desired. */ + int *xPtr, *yPtr; /* Filled with the upper-left hand corner, in + * pixels, of the bounding box for the character + * specified by index, if non-NULL. */ + int *widthPtr, *heightPtr; + /* Filled with the width and height of the + * bounding box for the character specified by + * index, if non-NULL. */ + { + WTextLayout *layoutPtr; + WLayoutChunk *chunkPtr; + int i, x, w; + Tk_Font tkfont; + TkFont *fontPtr; + + if (index < 0) { + return 0; + } + + layoutPtr = (WTextLayout *) layout; + chunkPtr = layoutPtr->chunks; + tkfont = layoutPtr->tkfont; + fontPtr = (TkFont *) tkfont; + + for (i = 0; i < layoutPtr->numChunks; i++) { + if (chunkPtr->numDisplayChars < 0) { + if (index == 0) { + x = chunkPtr->x; + w = chunkPtr->totalWidth; + goto check; + } + } else if (index < chunkPtr->numChars) { + if (xPtr != NULL) { + Tk_MeasureWChars(tkfont, chunkPtr->start, index, 0, 0, &x); + x += chunkPtr->x; + } + if (widthPtr != NULL) { + Tk_MeasureWChars(tkfont, chunkPtr->start + index, 1, 0, 0, &w); + } + goto check; + } + index -= chunkPtr->numChars; + chunkPtr++; + } + if (index == 0) { + /* + * Special case to get location just past last char in layout. + */ + + chunkPtr--; + x = chunkPtr->x + chunkPtr->totalWidth; + w = 0; + } else { + return 0; + } + + /* + * Ensure that the bbox lies within the text layout. This forces all + * chars that extend off the right edge of the text layout to have + * truncated widths, and all chars that are completely off the right + * edge of the text layout to peg to the edge and have 0 width. + */ + check: + if (yPtr != NULL) { + *yPtr = chunkPtr->y - fontPtr->fm.ascent; + } + if (heightPtr != NULL) { + *heightPtr = fontPtr->fm.ascent + fontPtr->fm.descent; + } + + if (x > layoutPtr->width) { + x = layoutPtr->width; + } + if (xPtr != NULL) { + *xPtr = x; + } + if (widthPtr != NULL) { + if (x + w > layoutPtr->width) { + w = layoutPtr->width - x; + } + *widthPtr = w; + } + + return 1; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_DistanceToWTextLayout -- + * + * Computes the distance in pixels from the given point to the + * given text layout. Non-displaying space characters that occur + * at the end of individual lines in the text layout are ignored + * for hit detection purposes. + * + * Results: + * The return value is 0 if the point (x, y) is inside the text + * layout. If the point isn't inside the text layout then the + * return value is the distance in pixels from the point to the + * text item. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + Tk_DistanceToWTextLayout(layout, x, y) + Tk_WTextLayout layout; /* Layout information, from a previous call + * to Tk_ComputeWTextLayout(). */ + int x, y; /* Coordinates of point to check, with + * respect to the upper-left corner of the + * text layout (in pixels). */ + { + int i, x1, x2, y1, y2, xDiff, yDiff, dist, minDist, ascent, descent; + WLayoutChunk *chunkPtr; + WTextLayout *layoutPtr; + TkFont *fontPtr; + + layoutPtr = (WTextLayout *) layout; + fontPtr = (TkFont *) layoutPtr->tkfont; + ascent = fontPtr->fm.ascent; + descent = fontPtr->fm.descent; + + minDist = 0; + chunkPtr = layoutPtr->chunks; + for (i = 0; i < layoutPtr->numChunks; i++) { + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing distance + * (but tab characters would still be considered). + */ + + chunkPtr++; + continue; + } + + x1 = chunkPtr->x; + y1 = chunkPtr->y - ascent; + x2 = chunkPtr->x + chunkPtr->displayWidth; + y2 = chunkPtr->y + descent; + + if (x < x1) { + xDiff = x1 - x; + } else if (x >= x2) { + xDiff = x - x2 + 1; + } else { + xDiff = 0; + } + + if (y < y1) { + yDiff = y1 - y; + } else if (y >= y2) { + yDiff = y - y2 + 1; + } else { + yDiff = 0; + } + if ((xDiff == 0) && (yDiff == 0)) { + return 0; + } + dist = (int) hypot((double) xDiff, (double) yDiff); + if ((dist < minDist) || (minDist == 0)) { + minDist = dist; + } + chunkPtr++; + } + return minDist; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_IntersectWTextLayout -- + * + * Determines whether a text layout lies entirely inside, + * entirely outside, or overlaps a given rectangle. Non-displaying + * space characters that occur at the end of individual lines in + * the text layout are ignored for intersection calculations. + * + * Results: + * The return value is -1 if the text layout is entirely outside of + * the rectangle, 0 if it overlaps, and 1 if it is entirely inside + * of the rectangle. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + Tk_IntersectWTextLayout(layout, x, y, width, height) + Tk_WTextLayout layout; /* Layout information, from a previous call + * to Tk_ComputeWTextLayout(). */ + int x, y; /* Upper-left hand corner, in pixels, of + * rectangular area to compare with text + * layout. Coordinates are with respect to + * the upper-left hand corner of the text + * layout itself. */ + int width, height; /* The width and height of the above + * rectangular area, in pixels. */ + { + int result, i, x1, y1, x2, y2; + WTextLayout *layoutPtr; + WLayoutChunk *chunkPtr; + TkFont *fontPtr; + int left, top, right, bottom; + + /* + * Scan the chunks one at a time, seeing whether each is entirely in, + * entirely out, or overlapping the rectangle. If an overlap is + * detected, return immediately; otherwise wait until all chunks have + * been processed and see if they were all inside or all outside. + */ + + layoutPtr = (WTextLayout *) layout; + chunkPtr = layoutPtr->chunks; + fontPtr = (TkFont *) layoutPtr->tkfont; + + left = x; + top = y; + right = x + width; + bottom = y + height; + + result = 0; + for (i = 0; i < layoutPtr->numChunks; i++) { + if (chunkPtr->start[0] == '\n') { + /* + * Newline characters are not counted when computing area + * intersection (but tab characters would still be considered). + */ + + chunkPtr++; + continue; + } + + x1 = chunkPtr->x; + y1 = chunkPtr->y - fontPtr->fm.ascent; + x2 = chunkPtr->x + chunkPtr->displayWidth; + y2 = chunkPtr->y + fontPtr->fm.descent; + + if ((right < x1) || (left >= x2) + || (bottom < y1) || (top >= y2)) { + if (result == 1) { + return 0; + } + result = -1; + } else if ((x1 < left) || (x2 >= right) + || (y1 < top) || (y2 >= bottom)) { + return 0; + } else if (result == -1) { + return 0; + } else { + result = 1; + } + chunkPtr++; + } + return result; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_WTextLayoutToPostscript -- + * + * Outputs the contents of a text layout in Postscript format. + * The set of lines in the text layout will be rendered by the user + * supplied Postscript function. The function should be of the form: + * + * justify x y string function -- + * + * Justify is -1, 0, or 1, depending on whether the following string + * should be left, center, or right justified, x and y is the + * location for the origin of the string, string is the sequence + * of characters to be printed, and function is the name of the + * caller-provided function; the function should leave nothing + * on the stack. + * + * The meaning of the origin of the string (x and y) depends on + * the justification. For left justification, x is where the + * left edge of the string should appear. For center justification, + * x is where the center of the string should appear. And for right + * justification, x is where the right edge of the string should + * appear. This behavior is necessary because, for example, right + * justified text on the screen is justified with screen metrics. + * The same string needs to be justified with printer metrics on + * the printer to appear in the correct place with respect to other + * similarly justified strings. In all circumstances, y is the + * location of the baseline for the string. + * + * Results: + * Interp->result is modified to hold the Postscript code that + * will render the text layout. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + void + Tk_WTextLayoutToPostscript(interp, layout) + Tcl_Interp *interp; /* Filled with Postscript code. */ + Tk_WTextLayout layout; /* The layout to be rendered. */ + { + #define MAXUSE 128 + char buf[MAXUSE+10]; + WLayoutChunk *chunkPtr; + int i, j, used, c, baseline; + WTextLayout *layoutPtr; + + layoutPtr = (WTextLayout *) layout; + chunkPtr = layoutPtr->chunks; + baseline = chunkPtr->y; + used = 0; + buf[used++] = '('; + for (i = 0; i < layoutPtr->numChunks; i++) { + if (baseline != chunkPtr->y) { + buf[used++] = ')'; + buf[used++] = '\n'; + buf[used++] = '('; + baseline = chunkPtr->y; + } + if (chunkPtr->numDisplayChars <= 0) { + if (chunkPtr->start[0] == '\t') { + buf[used++] = '\\'; + buf[used++] = 't'; + } + } else { + for (j = 0; j < chunkPtr->numDisplayChars; j++) { + c = chunkPtr->start[j] & 0xffff; + if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20)) { + /* + * Tricky point: the "03" is necessary in the sprintf + * below, so that a full three digits of octal are + * always generated. Without the "03", a number + * following this sequence could be interpreted by + * Postscript as part of this sequence. + */ + + sprintf(buf + used, "\\%03o", c); + used += 4; + } else if (c <= 0x7f) { + buf[used++] = c; + } else { + if ((c & 0x8080) == G2MASK) { + /* Kana */ + sprintf(buf + used, "\\%03o", 0x8e); /* SS2 */ + used += 4; + /* Map to GL */ + sprintf(buf + used, "\\%03o", c & 0xff); + used += 4; + } else { + /* Kanji */ + sprintf(buf + used, "\\%03o", c >> 8); + used += 4; + sprintf(buf + used, "\\%03o", c & 0xff); + used += 4; + } + } + if (used >= MAXUSE) { + buf[used] = '\0'; + Tcl_AppendResult(interp, buf, (char *) NULL); + used = 0; + } + } + } + if (used >= MAXUSE) { + /* + * If there are a whole bunch of returns or tabs in a row, + * then buf[] could get filled up. + */ + + buf[used] = '\0'; + Tcl_AppendResult(interp, buf, (char *) NULL); + used = 0; + } + chunkPtr++; + } + buf[used++] = ')'; + buf[used++] = '\n'; + buf[used] = '\0'; + Tcl_AppendResult(interp, buf, (char *) NULL); + } + + /* + *--------------------------------------------------------------------------- + * + * NewWChunk -- + * + * Helper function for Tk_ComputeWTextLayout(). Encapsulates a + * measured set of characters in a chunk that can be quickly + * drawn. + * + * Results: + * A pointer to the new chunk in the text layout. + * + * Side effects: + * The text layout is reallocated to hold more chunks as necessary. + * + * Currently, Tk_ComputeWTextLayout() stores contiguous ranges of + * "normal" characters in a chunk, along with individual tab + * and newline chars in their own chunks. All characters in the + * text layout are accounted for. + * + *--------------------------------------------------------------------------- + */ + static WLayoutChunk * + NewWChunk(layoutPtrPtr, maxPtr, start, numChars, curX, newX, y) + WTextLayout **layoutPtrPtr; + int *maxPtr; + CONST wchar *start; + int numChars; + int curX; + int newX; + int y; + { + WTextLayout *layoutPtr; + WLayoutChunk *chunkPtr; + int maxChunks; + size_t s; + + layoutPtr = *layoutPtrPtr; + maxChunks = *maxPtr; + if (layoutPtr->numChunks == maxChunks) { + maxChunks *= 2; + s = sizeof(WTextLayout) + ((maxChunks - 1) * sizeof(WLayoutChunk)); + layoutPtr = (WTextLayout *) ckrealloc((char *) layoutPtr, s); + + *layoutPtrPtr = layoutPtr; + *maxPtr = maxChunks; + } + chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks]; + chunkPtr->start = start; + chunkPtr->numChars = numChars; + chunkPtr->numDisplayChars = numChars; + chunkPtr->x = curX; + chunkPtr->y = y; + chunkPtr->totalWidth = newX - curX; + chunkPtr->displayWidth = newX - curX; + layoutPtr->numChunks++; + + return chunkPtr; + } + + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/generic/tkWindow.c ./generic/tkWindow.c *** ../../tk8.0.5/generic/tkWindow.c Thu Oct 1 04:01:20 1998 --- ./generic/tkWindow.c Mon May 10 19:10:18 1999 *************** *** 111,116 **** --- 111,121 ---- {"font", NULL, Tk_FontObjCmd, 1}, {"grab", Tk_GrabCmd, NULL, 0}, {"grid", Tk_GridCmd, NULL, 1}, + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + {"imconfigure", NULL, Tk_ImconfigureObjCmd, 1}, + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ {"image", Tk_ImageCmd, NULL, 1}, {"lower", Tk_LowerCmd, NULL, 1}, {"option", Tk_OptionCmd, NULL, 1}, *************** *** 127,132 **** --- 132,141 ---- {"update", Tk_UpdateCmd, NULL, 1}, {"winfo", NULL, Tk_WinfoObjCmd, 1}, {"wm", Tk_WmCmd, NULL, 0}, + #ifdef KANJI + {"kanjiInput", Tk_KanjiInputCmd, NULL, 1}, + {"kinsoku", NULL, Tk_KinsokuObjCmd, 1}, + #endif /* KANJI */ /* * Widget class commands. *************** *** 208,213 **** --- 217,230 ---- char *name)); static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr)); static void UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr)); + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + static void IMInstantiateCallback _ANSI_ARGS_ ((Display *display, + XPointer clientData, XPointer callData)); + static void IMDestroyCallback _ANSI_ARGS_ ((XIM im, XPointer clientData, + XPointer callData)); + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ /* *---------------------------------------------------------------------- *************** *** 545,550 **** --- 562,570 ---- winPtr->handlerList = NULL; #ifdef TK_USE_INPUT_METHODS winPtr->inputContext = NULL; + #ifdef XIM_IMPROVE + winPtr->icAttr = TkpAllocICAttribute((Tk_Window)winPtr); + #endif /* XIM_IMPROVE */ #endif /* TK_USE_INPUT_METHODS */ winPtr->tagPtr = NULL; winPtr->numTags = 0; *************** *** 722,727 **** --- 742,751 ---- if (tkwin == NULL) { return NULL; } + #ifdef KANJI + TkSelInit(tkwin); + TkpKinsokuPkgInit(); + #endif /* KANJI */ /* * Create the TkMainInfo structure for this application, and set *************** *** 921,927 **** --- 945,969 ---- * situation where the parent is ".". */ + #ifdef KANJI + char *lastP = NULL; + char *end = pathName + strlen(pathName); + p = pathName; + + while (p < end) { + if (IS_KANJISTART(UCHAR(*p))) { + p += Tcl_KanjiSkip(p, end, NULL); + continue; + } + if (*p == '.') { + lastP = p; + } + p++; + } + p = lastP; + #else p = strrchr(pathName, '.'); + #endif /* KANJI */ if (p == NULL) { Tcl_AppendResult(interp, "bad window path name \"", pathName, "\"", (char *) NULL); *************** *** 1175,1183 **** --- 1217,1240 ---- TkEventDeadWindow(winPtr); TkBindDeadWindow(winPtr); #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + if (winPtr->inputContext == winPtr->dispPtr->lastFocusedIC) { + winPtr->dispPtr->lastFocusedIC = None; + } + #endif /* XIM_IMPROVE */ if (winPtr->inputContext != NULL) { + SetICState(winPtr->icAttr, (IC_DESTROYED|IC_ASSOC_WIN_DELETED)); XDestroyIC(winPtr->inputContext); } + #ifdef XIM_IMPROVE + /* + * Delete IC first because XDestroyIC() generate callbacks. + */ + if (winPtr->icAttr != NULL) { + TkpDeleteICAttribute(tkwin, winPtr->icAttr); + winPtr->icAttr = NULL; + } + #endif /* XIM_IMPROVE */ #endif /* TK_USE_INPUT_METHODS */ if (winPtr->tagPtr != NULL) { TkFreeBindingTags(winPtr); *************** *** 1279,1284 **** --- 1336,1355 ---- if (dispPtr->name != NULL) { ckfree(dispPtr->name); } + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + if (dispPtr->modifiers != NULL) { + ckfree(dispPtr->modifiers); + dispPtr->modifiers = NULL; + } + if (dispPtr->imSupportedStyle != NULL) { + XFree(dispPtr->imSupportedStyle); + dispPtr->imSupportedStyle = NULL; + } + dispPtr->imIcValues = 0; + dispPtr->lastFocusedIC = None; + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ Tcl_DeleteHashTable(&(dispPtr->winTable)); *************** *** 2328,2333 **** --- 2399,2520 ---- return ((TkWindow *) tkwin)->mainPtr->strictMotif; } + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + /* + *---------------------------------------------------------------------- + * + * IMInstantiateCallback + * + * Whenever IM server become available, this function will be called. + * + * Results: + * OpenIM() is called. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + void + IMInstantiateCallback(display, clientData, callData) + Display *display; + XPointer clientData; + XPointer callData; + { + TkDisplay *dispPtr = (TkDisplay *)clientData; + + if (display == dispPtr->display && + dispPtr->inputMethod == NULL) { + #ifdef XIM_DEBUG + fprintf(stderr, "debugIM: IM launch.\n"); + #endif /* XIM_DEBUG */ + OpenIM(dispPtr); + } + } + + /* + *---------------------------------------------------------------------- + * + * IMDestroyCallback + * + * Whenever IM server stops the service, this function will be called. + * + * Results: + * the XIM opened before is marked as unusable. + * + * Side effects: + * XIC using this XIM will be useless. + * + *---------------------------------------------------------------------- + */ + void + IMDestroyCallback(im, clientData, callData) + XIM im; + XPointer clientData; + XPointer callData; + { + TkDisplay *dispPtr = (TkDisplay *)clientData; + if (im == dispPtr->inputMethod) { + Tcl_HashTable winTable = dispPtr->winTable; + Tcl_HashEntry *entry = NULL; + Tcl_HashSearch search; + TkWindow *winPtr; + + /* + * We must not call XCloseIM() or XDestroyIC(). + * because the XIM and XIC are destroyed by Xlib + * automatically. + */ + #ifdef XIM_DEBUG + fprintf(stderr, "debugIM: IM server stoped.\n"); + #endif /* XIM_DEBUG */ + for (entry = Tcl_FirstHashEntry(&winTable, &search); entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + winPtr = (TkWindow *)Tcl_GetHashValue(entry); + if (winPtr->dispPtr->display == dispPtr->display && + winPtr->dispPtr->inputMethod == im) { + winPtr->flags &= ~(TK_CHECKED_IC); + if (winPtr->inputContext != NULL) { + TkpDeleteIMGenericHandler((Tk_Window)winPtr); + } + winPtr->inputContext = NULL; + if (winPtr->icAttr != NULL) { + TkpDeleteICAttribute((Tk_Window)winPtr, winPtr->icAttr); + } + winPtr->icAttr = TkpAllocICAttribute((Tk_Window)winPtr); + #ifdef XIM_DEBUG + fprintf(stderr, "debugIM: XIC of '%s' is NULL'd.\n", + (winPtr->pathName != NULL) ? winPtr->pathName : "??"); + #endif /* XIM_DEBUG */ + } + } + if (dispPtr->modifiers != NULL) { + ckfree(dispPtr->modifiers); + dispPtr->modifiers = NULL; + } + if (dispPtr->imSupportedStyle != NULL) { + XFree(dispPtr->imSupportedStyle); + dispPtr->imSupportedStyle = NULL; + } + dispPtr->inputMethod = NULL; + dispPtr->imIcValues = 0; + dispPtr->lastFocusedIC = None; + #ifdef HAVE_XIMREGINSTCB + #ifdef NO_XIDPROC + XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL, + (XIMProc)IMInstantiateCallback, (XPointer *)dispPtr); + #else + XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL, + (XIDProc)IMInstantiateCallback, (XPointer)dispPtr); + #endif /* NO_XIDPROC */ + #endif /* HAVE_XIMREGINSTCB */ + } + } + + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ /* *-------------------------------------------------------------- * *************** *** 2354,2367 **** --- 2541,2648 ---- #ifndef TK_USE_INPUT_METHODS return; #else + #ifndef XIM_IMPROVE unsigned short i; + #endif /* !XIM_IMPROVE */ XIMStyles *stylePtr; + #ifdef XIM_IMPROVE + XIMValuesList *ICValuesList = NULL; + #ifdef USE_XOC + dispPtr->outputMethod = NULL; + #endif /* USE_XOC */ + dispPtr->inputMethod = NULL; + dispPtr->imSupportedStyle = NULL; + dispPtr->imIcValues = 0; + dispPtr->modifiers = NULL; + dispPtr->lastFocusedIC = None; + stylePtr = NULL; + + if (setlocale(LC_ALL, "") == NULL) { + /* + * Well, What should I do ? Are there any Xlib implementation + * like "C" locale supports ANY locales ? I doubt it. + * Anyway, try "C". + */ + if (setlocale(LC_ALL, "C") == NULL) { + /* + * How BOGUS this libc is ! + * I want to call panic() in such a case :( + * Man, replace your WHOLE libc. + */ + return; + } + } + if (XSupportsLocale() != True) { + return; + } + #endif /* XIM_IMPROVE */ + #ifdef XIM_IMPROVE + { + /* + * The user who want to specify modifier should set XMODIFIERS + * environment variable. + */ + char *modifiers = XSetLocaleModifiers(""); + if (modifiers == NULL) { + dispPtr->modifiers = NULL; + } else { + int len = strlen(modifiers); + dispPtr->modifiers = (char *)ckalloc(sizeof(char) * (len + 1)); + memcpy((VOID *)(dispPtr->modifiers), (VOID *)modifiers, (unsigned int)len); + dispPtr->modifiers[len] = 0; + } + } + #ifdef USE_XOC + dispPtr->outputMethod = XOpenOM(dispPtr->display, NULL, NULL, NULL); + if (dispPtr->outputMethod == NULL) { + goto error; + } + #endif /* USE_XOC */ + #endif /* XIM_IMPROVE */ dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL); if (dispPtr->inputMethod == NULL) { + #ifdef XIM_IMPROVE + /* + * Maybe no input method is available rite now. + * Try to register instatntiate callback. + */ + #ifdef HAVE_XIMREGINSTCB + #ifdef NO_XIDPROC + XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL, + (XIMProc)IMInstantiateCallback, (XPointer *)dispPtr); + #else + XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL, + (XIDProc)IMInstantiateCallback, (XPointer)dispPtr); + #endif /* NO_XIDPROC */ + #endif /* HAVE_XIMREGINSTCB */ + goto error; + #else return; + #endif /* XIM_IMPROVE */ } + #ifdef XIM_IMPROVE + if ((XGetIMValues(dispPtr->inputMethod, + XNQueryInputStyle, &stylePtr, + XNQueryICValuesList, &ICValuesList, + NULL) != NULL) || + (stylePtr == NULL) || + (ICValuesList == NULL)) { + goto error; + } else { + #ifdef XNDestroyCallback + dispPtr->destroyCallback.client_data = (XPointer)dispPtr; + dispPtr->destroyCallback.callback = (XIMProc)IMDestroyCallback; + (void)XSetIMValues(dispPtr->inputMethod, + XNDestroyCallback, &(dispPtr->destroyCallback), NULL); + #endif /* XNDestroyCallback */ + dispPtr->imIcValues = TkpGetSupportedICAttribute(ICValuesList); + dispPtr->imSupportedStyle = stylePtr; + XFree(ICValuesList); + return; + } + #else if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr, NULL) != NULL) || (stylePtr == NULL)) { goto error; *************** *** 2373,2381 **** --- 2654,2672 ---- return; } } + #endif /* XIM_IMPROVE */ XFree(stylePtr); error: + #ifdef XIM_IMPROVE + if (dispPtr->modifiers != NULL) { + ckfree(dispPtr->modifiers); + dispPtr->modifiers = NULL; + } + dispPtr->imSupportedStyle = NULL; + dispPtr->imIcValues = 0; + dispPtr->lastFocusedIC = None; + #endif /* XIM_IMPROVE */ /* * Should close the input method, but this causes core dumps on some *************** *** 2476,2481 **** --- 2767,2786 ---- if (displayPtr->name != (char *) NULL) { ckfree(displayPtr->name); } + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + if (displayPtr->modifiers != NULL) { + ckfree(displayPtr->modifiers); + displayPtr->modifiers = NULL; + } + if (displayPtr->imSupportedStyle != NULL) { + XFree(displayPtr->imSupportedStyle); + displayPtr->imSupportedStyle = NULL; + } + displayPtr->imIcValues = 0; + displayPtr->lastFocusedIC = None; + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ Tcl_DeleteHashTable(&(displayPtr->winTable)); TkpCloseDisplay(displayPtr); } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/README ./library/demos.jp/README *** ../../tk8.0.5/library/demos.jp/README Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/README Thu Apr 1 00:08:24 1999 *************** *** 0 **** --- 1,46 ---- + This directory contains a collection of programs to demonstrate + the features of the Tk toolkit. The programs are all scripts for + "wish", a windowing shell. If wish has been installed in /usr/local + then you can invoke any of the programs in this directory just + by typing its file name to your command shell. Otherwise invoke + wish with the file as its first argument, e.g., "wish hello". + The rest of this file contains a brief description of each program. + Files with names ending in ".tcl" are procedure packages used by one + or more of the demo programs; they can't be used as programs by + themselves so they aren't described below. + + hello - Creates a single button; if you click on it, a message + is typed and the application terminates. + + widget - Contains a collection of demonstrations of the widgets + currently available in the Tk library. Most of the .tcl + files are scripts for individual demos available through + the "widget" program. + + ixset - A simple Tk-based wrapper for the "xset" program, which + allows you to interactively query and set various X options + such as mouse acceleration and bell volume. Thanks to + Pierre David for contributing this example. + + rolodex - A mock-up of a simple rolodex application. It has much of + the user interface for such an application but no back-end + database. This program was written in response to Tom + LaStrange's toolkit benchmark challenge. + + tcolor - A color editor. Allows you to edit colors in several + different ways, and will also perform automatic updates + using "send". + + rmt - Allows you to "hook-up" remotely to any Tk application + on the display. Select an application with the menu, + then just type commands: they'll go to that application. + + timer - Displays a seconds timer with start and stop buttons. + Control-c and control-q cause it to exit. + + browse - A simple directory browser. Invoke it with and argument + giving the name of the directory you'd like to browse. + Double-click on files or subdirectories to browse them. + Control-c and control-q cause the program to exit. + + RCS: @(#) $Id: README,v 1.1 1999/03/31 15:08:24 m-hirano Exp $ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/README.JP ./library/demos.jp/README.JP *** ../../tk8.0.5/library/demos.jp/README.JP Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/README.JP Thu Apr 1 23:57:12 1999 *************** *** 0 **** --- 1,10 ---- + これは tk8.0.5 付属の Widget Tour デモを日本語化したものです。 + $tk_library の下に demos.jp というディレクトリ名で置いてください。 + + スクリプトの漢字コードは JIS になっています。tk8.1b2 で実行する場合に + は Tcl の system encoding にあわせて変換してください。 + + メッセージの日本語訳に関しては widget-demo-tk4.0jp.tar.gz から流用させ + ていただきました。感謝します。 + + Atsushi Nemoto (anemo@mba.sphere.ne.jp) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/arrow.tcl ./library/demos.jp/arrow.tcl *** ../../tk8.0.5/library/demos.jp/arrow.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/arrow.tcl Thu Apr 1 00:08:24 1999 *************** *** 0 **** --- 1,240 ---- + # arrow.tcl -- + # + # This demonstration script creates a canvas widget that displays a + # large line with an arrowhead whose shape can be edited interactively. + # + # RCS: @(#) $Id: arrow.tcl,v 1.1 1999/03/31 15:08:24 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # arrowSetup -- + # This procedure regenerates all the text and graphics in the canvas + # window. It's called when the canvas is initially created, and also + # whenever any of the parameters of the arrow head are changed + # interactively. + # + # Arguments: + # c - Name of the canvas widget. + + proc arrowSetup c { + upvar #0 demo_arrowInfo v + + # Remember the current box, if there is one. + + set tags [$c gettags current] + if {$tags != ""} { + set cur [lindex $tags [lsearch -glob $tags box?]] + } else { + set cur "" + } + + # Create the arrow and outline. + + $c delete all + eval "$c create line $v(x1) $v(y) $v(x2) $v(y) -width [expr 10*$v(width)] \ + -arrowshape {[expr 10*$v(a)] [expr 10*$v(b)] [expr 10*$v(c)]} \ + -arrow last $v(bigLineStyle)" + set xtip [expr $v(x2)-10*$v(b)] + set deltaY [expr 10*$v(c)+5*$v(width)] + $c create line $v(x2) $v(y) $xtip [expr $v(y)+$deltaY] \ + [expr $v(x2)-10*$v(a)] $v(y) $xtip [expr $v(y)-$deltaY] \ + $v(x2) $v(y) -width 2 -capstyle round -joinstyle round + + # Create the boxes for reshaping the line and arrowhead. + + eval "$c create rect [expr $v(x2)-10*$v(a)-5] [expr $v(y)-5] \ + [expr $v(x2)-10*$v(a)+5] [expr $v(y)+5] $v(boxStyle) \ + -tags {box1 box}" + eval "$c create rect [expr $xtip-5] [expr $v(y)-$deltaY-5] \ + [expr $xtip+5] [expr $v(y)-$deltaY+5] $v(boxStyle) \ + -tags {box2 box}" + eval "$c create rect [expr $v(x1)-5] [expr $v(y)-5*$v(width)-5] \ + [expr $v(x1)+5] [expr $v(y)-5*$v(width)+5] $v(boxStyle) \ + -tags {box3 box}" + if {$cur != ""} { + eval $c itemconfigure $cur $v(activeStyle) + } + + # Create three arrows in actual size with the same parameters + + $c create line [expr $v(x2)+50] 0 [expr $v(x2)+50] 1000 \ + -width 2 + set tmp [expr $v(x2)+100] + $c create line $tmp [expr $v(y)-125] $tmp [expr $v(y)-75] \ + -width $v(width) \ + -arrow both -arrowshape "$v(a) $v(b) $v(c)" + $c create line [expr $tmp-25] $v(y) [expr $tmp+25] $v(y) \ + -width $v(width) \ + -arrow both -arrowshape "$v(a) $v(b) $v(c)" + $c create line [expr $tmp-25] [expr $v(y)+75] [expr $tmp+25] \ + [expr $v(y)+125] -width $v(width) \ + -arrow both -arrowshape "$v(a) $v(b) $v(c)" + + # Create a bunch of other arrows and text items showing the + # current dimensions. + + set tmp [expr $v(x2)+10] + $c create line $tmp [expr $v(y)-5*$v(width)] \ + $tmp [expr $v(y)-$deltaY] \ + -arrow both -arrowshape $v(smallTips) + $c create text [expr $v(x2)+15] [expr $v(y)-$deltaY+5*$v(c)] \ + -text $v(c) -anchor w + set tmp [expr $v(x1)-10] + $c create line $tmp [expr $v(y)-5*$v(width)] \ + $tmp [expr $v(y)+5*$v(width)] \ + -arrow both -arrowshape $v(smallTips) + $c create text [expr $v(x1)-15] $v(y) -text $v(width) -anchor e + set tmp [expr $v(y)+5*$v(width)+10*$v(c)+10] + $c create line [expr $v(x2)-10*$v(a)] $tmp $v(x2) $tmp \ + -arrow both -arrowshape $v(smallTips) + $c create text [expr $v(x2)-5*$v(a)] [expr $tmp+5] \ + -text $v(a) -anchor n + set tmp [expr $tmp+25] + $c create line [expr $v(x2)-10*$v(b)] $tmp $v(x2) $tmp \ + -arrow both -arrowshape $v(smallTips) + $c create text [expr $v(x2)-5*$v(b)] [expr $tmp+5] \ + -text $v(b) -anchor n + + $c create text $v(x1) 310 -text "-width $v(width)" \ + -anchor w -font {Helvetica 18} + $c create text $v(x1) 330 -text "-arrowshape {$v(a) $v(b) $v(c)}" \ + -anchor w -font {Helvetica 18} + + incr v(count) + } + + set w .arrow + global tk_library + catch {destroy $w} + toplevel $w + wm title $w "Arrowhead Editor Demonstration" + wm iconname $w "arrow" + positionWindow $w + set c $w.c + + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "This widget allows you to experiment with different widths and arrowhead shapes for lines in canvases. To change the line width or the shape of the arrowhead, drag any of the three boxes attached to the oversized arrow. The arrows on the right give examples at normal scale. The text at the bottom shows the configuration options as you'd enter them for a canvas line item." \ + "$B$3$N(B widget $B$G!"%-%c%s%P%9$G;H$o$l$k%i%$%s$K$D$$$FMM!9$JI}$dLp0u$NF,$N7A$r;n$7$F$_$k$3$H$,$G$-$^$9!#@~$NI}$dLp0u$N7A$rJQ$($k$K$O!"3HBg$5$l$?Lp0u$K$D$$$F$$$k(B 3$B$D$N;M3Q$r%I%i%C%0$7$F$/$@$5$$!#1&B&$NLp0u$OIaDL$NBg$-$5$G$N%5%s%W%k$r<($7$F$$$^$9!#2<$N%F%-%9%H$O%i%$%s%"%$%F%`$KBP$9$k@_Dj%*%W%7%g%s$G$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + canvas $c -width 500 -height 350 -relief sunken -borderwidth 2 + pack $c -expand yes -fill both + + set demo_arrowInfo(a) 8 + set demo_arrowInfo(b) 10 + set demo_arrowInfo(c) 3 + set demo_arrowInfo(width) 2 + set demo_arrowInfo(motionProc) arrowMoveNull + set demo_arrowInfo(x1) 40 + set demo_arrowInfo(x2) 350 + set demo_arrowInfo(y) 150 + set demo_arrowInfo(smallTips) {5 5 2} + set demo_arrowInfo(count) 0 + if {[winfo depth $c] > 1} { + set demo_arrowInfo(bigLineStyle) "-fill SkyBlue1" + set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 1" + set demo_arrowInfo(activeStyle) "-fill red -outline black -width 1" + } else { + set demo_arrowInfo(bigLineStyle) "-fill black \ + -stipple @[file join $tk_library demos.jp images grey.25]" + set demo_arrowInfo(boxStyle) "-fill {} -outline black -width 1" + set demo_arrowInfo(activeStyle) "-fill black -outline black -width 1" + } + arrowSetup $c + $c bind box "$c itemconfigure current $demo_arrowInfo(activeStyle)" + $c bind box "$c itemconfigure current $demo_arrowInfo(boxStyle)" + $c bind box " " + $c bind box " " + $c bind box1 <1> {set demo_arrowInfo(motionProc) arrowMove1} + $c bind box2 <1> {set demo_arrowInfo(motionProc) arrowMove2} + $c bind box3 <1> {set demo_arrowInfo(motionProc) arrowMove3} + $c bind box "\$demo_arrowInfo(motionProc) $c %x %y" + bind $c "arrowSetup $c" + + # arrowMove1 -- + # This procedure is called for each mouse motion event on box1 (the + # one at the vertex of the arrow). It updates the controlling parameters + # for the line and arrowhead. + # + # Arguments: + # c - The name of the canvas window. + # x, y - The coordinates of the mouse. + + proc arrowMove1 {c x y} { + upvar #0 demo_arrowInfo v + set newA [expr ($v(x2)+5-round([$c canvasx $x]))/10] + if {$newA < 0} { + set newA 0 + } + if {$newA > 25} { + set newA 25 + } + if {$newA != $v(a)} { + $c move box1 [expr 10*($v(a)-$newA)] 0 + set v(a) $newA + } + } + + # arrowMove2 -- + # This procedure is called for each mouse motion event on box2 (the + # one at the trailing tip of the arrowhead). It updates the controlling + # parameters for the line and arrowhead. + # + # Arguments: + # c - The name of the canvas window. + # x, y - The coordinates of the mouse. + + proc arrowMove2 {c x y} { + upvar #0 demo_arrowInfo v + set newB [expr ($v(x2)+5-round([$c canvasx $x]))/10] + if {$newB < 0} { + set newB 0 + } + if {$newB > 25} { + set newB 25 + } + set newC [expr ($v(y)+5-round([$c canvasy $y])-5*$v(width))/10] + if {$newC < 0} { + set newC 0 + } + if {$newC > 20} { + set newC 20 + } + if {($newB != $v(b)) || ($newC != $v(c))} { + $c move box2 [expr 10*($v(b)-$newB)] [expr 10*($v(c)-$newC)] + set v(b) $newB + set v(c) $newC + } + } + + # arrowMove3 -- + # This procedure is called for each mouse motion event on box3 (the + # one that controls the thickness of the line). It updates the + # controlling parameters for the line and arrowhead. + # + # Arguments: + # c - The name of the canvas window. + # x, y - The coordinates of the mouse. + + proc arrowMove3 {c x y} { + upvar #0 demo_arrowInfo v + set newWidth [expr ($v(y)+2-round([$c canvasy $y]))/5] + if {$newWidth < 0} { + set newWidth 0 + } + if {$newWidth > 20} { + set newWidth 20 + } + if {$newWidth != $v(width)} { + $c move box3 0 [expr 5*($v(width)-$newWidth)] + set v(width) $newWidth + } + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/bind.tcl ./library/demos.jp/bind.tcl *** ../../tk8.0.5/library/demos.jp/bind.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/bind.tcl Thu Apr 1 00:08:25 1999 *************** *** 0 **** --- 1,88 ---- + # bind.tcl -- + # + # This demonstration script creates a text widget with bindings set + # up for hypertext-like effects. + # + # RCS: @(#) $Id: bind.tcl,v 1.1 1999/03/31 15:08:25 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .bind + catch {destroy $w} + toplevel $w + wm title $w "Text Demonstration - Tag Bindings" + wm iconname $w "bind" + positionWindow $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + text $w.text -yscrollcommand "$w.scroll set" -setgrid true \ + -width 60 -height 24 -font $font -wrap word + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + + # Set up display styles. + + if {[winfo depth $w] > 1} { + set bold "-background #43ce80 -relief raised -borderwidth 1" + set normal "-background {} -relief flat" + } else { + set bold "-foreground white -background black" + set normal "-foreground {} -background {}" + } + + # Add text to widget. + + $w.text insert 0.0 [langSel {\ + The same tag mechanism that controls display styles in text widgets can also be used to associate Tcl commands with regions of text, so that mouse or keyboard actions on the text cause particular Tcl commands to be invoked. For example, in the text below the descriptions of the canvas demonstrations have been tagged. When you move the mouse over a demo description the description lights up, and when you press button 1 over a description then that particular demonstration is invoked. + + } {\ + $B%F%-%9%H(Bwidget$B$NI=<(%9%?%$%k$r@)8f$9$k$N$HF1$8%?%0$N%a%+%K%:%`$r;H$C$F!"%F%-%9%H$K(BTcl$B$N%3%^%s%I$r3d$jEv$F$k$3$H$,$G$-$^$9!#$3$l$K$h$j!"%^%&%9$d%-!<%\!<%I$N%"%/%7%g%s$GFCDj$N(BTcl$B$N%3%^%s%I$,e$K;}$C$F$$$/$H@bL@J8$,8w$j!"%\%?%s(B1$B$r2!$9$H$=$N@bL@$N%G%b$,;O$^$j$^$9!#(B + + }] + $w.text insert end \ + [langSel {1. Samples of all the different types of items that can be created in canvas widgets.} \ + {1. $B%-%c%s%P%9(B widget $B$K:n$k$3$H$N$G$-$k%"%$%F%`$N "$w.text tag configure $tag $bold" + $w.text tag bind $tag "$w.text tag configure $tag $normal" + } + $w.text tag bind d1 <1> {source [file join $tk_library demos.jp items.tcl]} + $w.text tag bind d2 <1> {source [file join $tk_library demos.jp plot.tcl]} + $w.text tag bind d3 <1> {source [file join $tk_library demos.jp ctext.tcl]} + $w.text tag bind d4 <1> {source [file join $tk_library demos.jp arrow.tcl]} + $w.text tag bind d5 <1> {source [file join $tk_library demos.jp ruler.tcl]} + $w.text tag bind d6 <1> {source [file join $tk_library demos.jp cscroll.tcl]} + + $w.text mark set insert 0.0 + $w.text configure -state disabled diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/bitmap.tcl ./library/demos.jp/bitmap.tcl *** ../../tk8.0.5/library/demos.jp/bitmap.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/bitmap.tcl Thu Apr 1 00:08:25 1999 *************** *** 0 **** --- 1,57 ---- + # bitmap.tcl -- + # + # This demonstration script creates a toplevel window that displays + # all of Tk's built-in bitmaps. + # + # RCS: @(#) $Id: bitmap.tcl,v 1.1 1999/03/31 15:08:25 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # bitmapRow -- + # Create a row of bitmap items in a window. + # + # Arguments: + # w - The window that is to contain the row. + # args - The names of one or more bitmaps, which will be displayed + # in a new row across the bottom of w along with their + # names. + + proc bitmapRow {w args} { + frame $w + pack $w -side top -fill both + set i 0 + foreach bitmap $args { + frame $w.$i + pack $w.$i -side left -fill both -pady .25c -padx .25c + label $w.$i.bitmap -bitmap $bitmap + label $w.$i.label -text $bitmap -width 9 + pack $w.$i.label $w.$i.bitmap -side bottom + incr i + } + } + + set w .bitmap + global tk_library + catch {destroy $w} + toplevel $w + wm title $w "Bitmap Demonstration" + wm iconname $w "bitmap" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "This window displays all of Tk's built-in bitmaps, along with the names you can use for them in Tcl scripts." \ + "$B$3$N%&%#%s%I%&$K$O!"(BTk $B$KAH$_9~$^$l$?$9$Y$F$N%S%C%H%^%C%W$,!"$=$l$i$NL>A0$H6&$KI=<($5$l$F$$$^$9!#(BTcl $B$N%9%/%j%W%HCf$G$O!"$=$l$>$l$NL>A0$rMQ$$$F;2>H$7$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame + bitmapRow $w.frame.0 error gray12 gray25 gray50 gray75 + bitmapRow $w.frame.1 hourglass info question questhead warning + pack $w.frame -side top -expand yes -fill both diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/browse ./library/demos.jp/browse *** ../../tk8.0.5/library/demos.jp/browse Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/browse Thu Apr 1 00:08:26 1999 *************** *** 0 **** --- 1,56 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # browse -- + # This script generates a directory browser, which lists the working + # directory and allows you to open files or subdirectories by + # double-clicking. + # + # RCS: @(#) $Id: browse,v 1.1 1999/03/31 15:08:26 m-hirano Exp $ + + # Create a scrollbar on the right side of the main window and a listbox + # on the left side. + + scrollbar .scroll -command ".list yview" + pack .scroll -side right -fill y + listbox .list -yscroll ".scroll set" -relief sunken -width 20 -height 20 \ + -setgrid yes + pack .list -side left -fill both -expand yes + wm minsize . 1 1 + + # The procedure below is invoked to open a browser on a given file; if the + # file is a directory then another instance of this program is invoked; if + # the file is a regular file then the Mx editor is invoked to display + # the file. + + proc browse {dir file} { + global env + if {[string compare $dir "."] != 0} {set file $dir/$file} + if [file isdirectory $file] { + exec browse $file & + } else { + if [file isfile $file] { + if [info exists env(EDITOR)] { + eval exec $env(EDITOR) $file & + } else { + exec xedit $file & + } + } else { + puts stdout "\"$file\" isn't a directory or regular file" + } + } + } + + # Fill the listbox with a list of all the files in the directory (run + # the "ls" command to get that information). + + if $argc>0 {set dir [lindex $argv 0]} else {set dir "."} + foreach i [exec ls -a $dir] { + .list insert end $i + } + + # Set up bindings for the browser. + + bind all {destroy .} + bind .list {foreach i [selection get] {browse $dir $i}} diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/button.tcl ./library/demos.jp/button.tcl *** ../../tk8.0.5/library/demos.jp/button.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/button.tcl Thu Apr 1 00:08:26 1999 *************** *** 0 **** --- 1,38 ---- + # button.tcl -- + # + # This demonstration script creates a toplevel window containing + # several button widgets. + # + # RCS: @(#) $Id: button.tcl,v 1.1 1999/03/31 15:08:26 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .button + catch {destroy $w} + toplevel $w + wm title $w "Button Demonstration" + wm iconname $w "button" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "If you click on any of the four buttons below, the background of the button area will change to the color indicated in the button. You can press Tab to move among the buttons, then press Space to invoke the current button." \ + "$B%\%?%s$r%/%j%C%/$9$k$H!"%\%?%s$NGX7J?'$,$=$N%\%?%s$K=q$+$l$F$$$k?'$K$J$j$^$9!#%\%?%s$+$i%\%?%s$X$N0\F0$O%?%V$r2!$9$3$H$G$b2DG=$G$9!#$^$?%9%Z!<%9$GH(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + button $w.b1 -text "Peach Puff" -width 10 \ + -command "$w config -bg PeachPuff1; $w.buttons config -bg PeachPuff1" + button $w.b2 -text "Light Blue" -width 10 \ + -command "$w config -bg LightBlue1; $w.buttons config -bg LightBlue1" + button $w.b3 -text "Sea Green" -width 10 \ + -command "$w config -bg SeaGreen2; $w.buttons config -bg SeaGreen2" + button $w.b4 -text "Yellow" -width 10 \ + -command "$w config -bg Yellow1; $w.buttons config -bg Yellow1" + pack $w.b1 $w.b2 $w.b3 $w.b4 -side top -expand yes -pady 2 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/cfont.tcl ./library/demos.jp/cfont.tcl *** ../../tk8.0.5/library/demos.jp/cfont.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/cfont.tcl Tue Apr 6 19:28:20 1999 *************** *** 0 **** --- 1,128 ---- + # cfont.tcl -- + # + # This demonstration script shows how to use compound founts. + # + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .cfont + catch {destroy $w} + toplevel $w + wm title $w "Compound Font Demonstration" + wm iconname $w "cfont" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "Choose the family, styles and size of both ASCII and KANJI fonts. Then press the \"Show Sample\" button to see a sample label of the compound font." \ + "ASCII $B%U%)%s%H$H4A;z%U%)%s%H$=$l$>$l$N%U%!%_%j!"%9%?%$%k!"Bg$-$5$rA*$s$G!V8+K\$rI=<(!W%\%?%s$r2!$7$F$/$@$5$$!#;XDj$7$?%3%s%Q%&%s%I%U%)%s%H$N8+K\%i%Y%k$,I=<($5$l$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + button $w.buttons.sample -text [langSel "Show Sample" "$B8+K\$rI=<((B"] \ + -command "$B8+K\I=<((B $w $w.dialog" + pack $w.buttons.dismiss $w.buttons.code $w.buttons.sample -side left -expand 1 + + # set default settings + if {$tcl_platform(platform) == "windows"} { + set $B%U%!%_%j(B(ascii) {Courier} + set $B%U%!%_%j(B($B4A;z(B) {$B#M#S(B $B#P%4%7%C%/(B} + # In Windows, charset are ignored + set $BJ8;z%;%C%H(B(ascii) {deault} + set $BJ8;z%;%C%H(B($B4A;z(B) {shiftjis} + } else { + set $B%U%!%_%j(B(ascii) fixed + set $B%U%!%_%j(B($B4A;z(B) fixed + set $BJ8;z%;%C%H(B(ascii) iso8859 + set $BJ8;z%;%C%H(B($B4A;z(B) jisx0208.1983 + } + foreach type {ascii $B4A;z(B} { + set $BBg$-$5(B($type) 14 + set $BB@$5(B($type) normal + set $B79$-(B($type) roman + } + + foreach type {ascii $B4A;z(B} { + frame $w.$type + pack $w.$type -side top -expand yes -padx 10 -pady 10 -fill both + + label $w.$type.label -font {Helvetica14} \ + -text "[kstring toupper $type]:" -width 8 + pack $w.$type.label -side left + + frame $w.$type.family + label $w.$type.family.label -text [langSel "Family:" "$B%U%!%_%j(B:"] + pack $w.$type.family.label -side top -anchor w + scrollbar $w.$type.family.scroll -command "$w.$type.family.list yview" + listbox $w.$type.family.list -yscroll "$w.$type.family.scroll set" \ + -height 8 -setgrid 1 -exportselection false + pack $w.$type.family.list $w.$type.family.scroll -side left -fill y \ + -expand yes + eval $w.$type.family.list insert 0 [font families] + set index [lsearch -exact [font families] $$B%U%!%_%j(B($type)] + $w.$type.family.list activate $index + $w.$type.family.list see $index + $w.$type.family.list selection set $index + + frame $w.$type.style + foreach {label var values} [list \ + [langSel "Weight" "$BB@$5(B"] $BB@$5(B {normal bold} \ + [langSel "Slant" "$B79$-(B"] $B79$-(B {roman italic}] { + label $w.$type.style.$var -text "$label:" + pack $w.$type.style.$var -side top -anchor w + foreach value $values { + radiobutton $w.$type.style.$var$value -text $value \ + -variable ${var}($type) -value $value + pack $w.$type.style.$var$value -side top -anchor w + } + } + + frame $w.$type.size + label $w.$type.size.label -text [langSel "Size:" "$BBg$-$5(B:"] + pack $w.$type.size.label -side top -anchor w + scale $w.$type.size.scale -orient vertical -from 8 -to 32 \ + -variable $BBg$-$5(B($type) + pack $w.$type.size.scale -side left -fill y + + pack $w.$type.family $w.$type.style $w.$type.size -side left \ + -fill y -padx 15 + } + + proc $B8+K\I=<((B {w dialog} { + global $B%U%!%_%j(B $BBg$-$5(B $BB@$5(B $B79$-(B $BJ8;z%;%C%H(B + + if {![winfo exists $dialog]} { + set sample "The quick brown fox jumps over the lazy dog.\n$BAGAa$$Cc?'$N%-%D%M$,$&$9$N$m%$%L$N>e$rHt$S1[$($?!#(B\nThis is just a $B%5%s%W%k(B Text." + toplevel $dialog + wm title $dialog "Compound Sample" + label $dialog.sample -relief sunken -text $sample + pack $dialog.sample -side top -padx 5 -pady 5 + button $dialog.ok -text OK -command "destroy $dialog" -default active + bind $dialog "tkButtonInvoke $dialog.ok" + pack $dialog.ok -side bottom -pady 2 + } + + # set back to default font + $dialog.sample configure -font [lindex [$dialog.sample config -font] 3] + + catch {font delete $B%3%s%Q%&%s%I%U%)%s%H(B} + catch {font delete ascii$B%U%)%s%H(B} + catch {font delete $B4A;z%U%)%s%H(B} + + # create descendant fonts + foreach type {ascii $B4A;z(B} { + set $B%U%!%_%j(B($type) [$w.$type.family.list get [$w.$type.family.list curselection]] + font create ${type}$B%U%)%s%H(B \ + -family $$B%U%!%_%j(B($type) -size $$BBg$-$5(B($type) \ + -weight $$BB@$5(B($type) -slant $$B79$-(B($type) \ + -charset $$BJ8;z%;%C%H(B($type) + } + # create compound font + font create $B%3%s%Q%&%s%I%U%)%s%H(B -compound {ascii$B%U%)%s%H(B $B4A;z%U%)%s%H(B} + + $dialog.sample configure -font $B%3%s%Q%&%s%I%U%)%s%H(B + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/check.tcl ./library/demos.jp/check.tcl *** ../../tk8.0.5/library/demos.jp/check.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/check.tcl Thu Apr 1 00:08:26 1999 *************** *** 0 **** --- 1,35 ---- + # check.tcl -- + # + # This demonstration script creates a toplevel window containing + # several checkbuttons. + # + # RCS: @(#) $Id: check.tcl,v 1.1 1999/03/31 15:08:26 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .check + catch {destroy $w} + toplevel $w + wm title $w "Checkbutton Demonstration" + wm iconname $w "check" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "Three checkbuttons are displayed below. If you click on a button, it will toggle the button's selection state and set a Tcl variable to a value indicating the state of the checkbutton. Click the \"See Variables\" button to see the current values of the variables." \ + "$B2<$K$O(B 3 $B$D$N%A%'%C%/%\%?%s$,I=<($5$l$F$$$^$9!#%/%j%C%/$9$k$H%\%?%s$NA*Br>uBV$,JQ$o$j!"(BTcl $BJQ?t$K$=$N%\%?%s$N>uBV$r<($9CM$r@_Dj$7$^$9!#8=:_$NJQ?t$NCM$r8+$k$K$O!VJQ?t;2>H!W%\%?%s$r%/%j%C%/$7$F$/$@$5$$!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + button $w.buttons.vars -text [langSel "See Variables" "$BJQ?t;2>H(B"] \ + -command "showVars $w.dialog wipers brakes sober" + pack $w.buttons.dismiss $w.buttons.code $w.buttons.vars -side left -expand 1 + + checkbutton $w.b1 -text [langSel "Wipers OK" "$B%o%$%Q!<(B OK"] -variable wipers -relief flat + checkbutton $w.b2 -text [langSel "Brakes OK" "$B%V%l!<%-(B OK"] -variable brakes -relief flat + checkbutton $w.b3 -text [langSel "Driver Sober" "$B%I%i%$%P!H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + button $w.back -text [langSel "Set background color ..." "$BGX7J?'$r@_Dj(B ..."] \ + -command \ + "setColor $w $w.back background {-background -highlightbackground}" + button $w.fore -text [langSel "Set foreground color ..." "$BA07J?'$r@_Dj(B ..."] \ + -command \ + "setColor $w $w.back foreground -foreground" + + pack $w.back $w.fore -side top -anchor c -pady 2m + + proc setColor {w button name options} { + grab $w + set initialColor [$button cget -$name] + set color [tk_chooseColor -title "Choose a $name color" -parent $w \ + -initialcolor $initialColor] + if [string compare $color ""] { + setColor_helper $w $options $color + } + grab release $w + } + + proc setColor_helper {w options color} { + foreach option $options { + catch { + $w config $option $color + } + } + foreach child [winfo children $w] { + setColor_helper $child $options $color + } + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/colors.tcl ./library/demos.jp/colors.tcl *** ../../tk8.0.5/library/demos.jp/colors.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/colors.tcl Thu Apr 1 00:08:27 1999 *************** *** 0 **** --- 1,103 ---- + # colors.tcl -- + # + # This demonstration script creates a listbox widget that displays + # many of the colors from the X color database. You can click on + # a color to change the application's palette. + # + # RCS: @(#) $Id: colors.tcl,v 1.1 1999/03/31 15:08:27 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .colors + catch {destroy $w} + toplevel $w + wm title $w "Listbox Demonstration (colors)" + wm iconname $w "Listbox" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "A listbox containing several color names is displayed below, along with a scrollbar. You can scan the list either using the scrollbar or by dragging in the listbox window with button 2 pressed. If you double-click button 1 on a color, then the application's color palette will be set to match that color" \ + "$B2<$K$O?'$NL>A0$,F~$C$?%9%/%m!<%k%P!H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame -borderwidth 10 + pack $w.frame -side top -expand yes -fill y + + scrollbar $w.frame.scroll -command "$w.frame.list yview" + listbox $w.frame.list -yscroll "$w.frame.scroll set" \ + -width 20 -height 16 -setgrid 1 + pack $w.frame.list $w.frame.scroll -side left -fill y -expand 1 + + bind $w.frame.list { + tk_setPalette [selection get] + } + $w.frame.list insert 0 gray60 gray70 gray80 gray85 gray90 gray95 \ + snow1 snow2 snow3 snow4 seashell1 seashell2 \ + seashell3 seashell4 AntiqueWhite1 AntiqueWhite2 AntiqueWhite3 \ + AntiqueWhite4 bisque1 bisque2 bisque3 bisque4 PeachPuff1 \ + PeachPuff2 PeachPuff3 PeachPuff4 NavajoWhite1 NavajoWhite2 \ + NavajoWhite3 NavajoWhite4 LemonChiffon1 LemonChiffon2 \ + LemonChiffon3 LemonChiffon4 cornsilk1 cornsilk2 cornsilk3 \ + cornsilk4 ivory1 ivory2 ivory3 ivory4 honeydew1 honeydew2 \ + honeydew3 honeydew4 LavenderBlush1 LavenderBlush2 \ + LavenderBlush3 LavenderBlush4 MistyRose1 MistyRose2 \ + MistyRose3 MistyRose4 azure1 azure2 azure3 azure4 \ + SlateBlue1 SlateBlue2 SlateBlue3 SlateBlue4 RoyalBlue1 \ + RoyalBlue2 RoyalBlue3 RoyalBlue4 blue1 blue2 blue3 blue4 \ + DodgerBlue1 DodgerBlue2 DodgerBlue3 DodgerBlue4 SteelBlue1 \ + SteelBlue2 SteelBlue3 SteelBlue4 DeepSkyBlue1 DeepSkyBlue2 \ + DeepSkyBlue3 DeepSkyBlue4 SkyBlue1 SkyBlue2 SkyBlue3 \ + SkyBlue4 LightSkyBlue1 LightSkyBlue2 LightSkyBlue3 \ + LightSkyBlue4 SlateGray1 SlateGray2 SlateGray3 SlateGray4 \ + LightSteelBlue1 LightSteelBlue2 LightSteelBlue3 \ + LightSteelBlue4 LightBlue1 LightBlue2 LightBlue3 \ + LightBlue4 LightCyan1 LightCyan2 LightCyan3 LightCyan4 \ + PaleTurquoise1 PaleTurquoise2 PaleTurquoise3 PaleTurquoise4 \ + CadetBlue1 CadetBlue2 CadetBlue3 CadetBlue4 turquoise1 \ + turquoise2 turquoise3 turquoise4 cyan1 cyan2 cyan3 cyan4 \ + DarkSlateGray1 DarkSlateGray2 DarkSlateGray3 \ + DarkSlateGray4 aquamarine1 aquamarine2 aquamarine3 \ + aquamarine4 DarkSeaGreen1 DarkSeaGreen2 DarkSeaGreen3 \ + DarkSeaGreen4 SeaGreen1 SeaGreen2 SeaGreen3 SeaGreen4 \ + PaleGreen1 PaleGreen2 PaleGreen3 PaleGreen4 SpringGreen1 \ + SpringGreen2 SpringGreen3 SpringGreen4 green1 green2 \ + green3 green4 chartreuse1 chartreuse2 chartreuse3 \ + chartreuse4 OliveDrab1 OliveDrab2 OliveDrab3 OliveDrab4 \ + DarkOliveGreen1 DarkOliveGreen2 DarkOliveGreen3 \ + DarkOliveGreen4 khaki1 khaki2 khaki3 khaki4 \ + LightGoldenrod1 LightGoldenrod2 LightGoldenrod3 \ + LightGoldenrod4 LightYellow1 LightYellow2 LightYellow3 \ + LightYellow4 yellow1 yellow2 yellow3 yellow4 gold1 gold2 \ + gold3 gold4 goldenrod1 goldenrod2 goldenrod3 goldenrod4 \ + DarkGoldenrod1 DarkGoldenrod2 DarkGoldenrod3 DarkGoldenrod4 \ + RosyBrown1 RosyBrown2 RosyBrown3 RosyBrown4 IndianRed1 \ + IndianRed2 IndianRed3 IndianRed4 sienna1 sienna2 sienna3 \ + sienna4 burlywood1 burlywood2 burlywood3 burlywood4 wheat1 \ + wheat2 wheat3 wheat4 tan1 tan2 tan3 tan4 chocolate1 \ + chocolate2 chocolate3 chocolate4 firebrick1 firebrick2 \ + firebrick3 firebrick4 brown1 brown2 brown3 brown4 salmon1 \ + salmon2 salmon3 salmon4 LightSalmon1 LightSalmon2 \ + LightSalmon3 LightSalmon4 orange1 orange2 orange3 orange4 \ + DarkOrange1 DarkOrange2 DarkOrange3 DarkOrange4 coral1 \ + coral2 coral3 coral4 tomato1 tomato2 tomato3 tomato4 \ + OrangeRed1 OrangeRed2 OrangeRed3 OrangeRed4 red1 red2 red3 \ + red4 DeepPink1 DeepPink2 DeepPink3 DeepPink4 HotPink1 \ + HotPink2 HotPink3 HotPink4 pink1 pink2 pink3 pink4 \ + LightPink1 LightPink2 LightPink3 LightPink4 PaleVioletRed1 \ + PaleVioletRed2 PaleVioletRed3 PaleVioletRed4 maroon1 \ + maroon2 maroon3 maroon4 VioletRed1 VioletRed2 VioletRed3 \ + VioletRed4 magenta1 magenta2 magenta3 magenta4 orchid1 \ + orchid2 orchid3 orchid4 plum1 plum2 plum3 plum4 \ + MediumOrchid1 MediumOrchid2 MediumOrchid3 MediumOrchid4 \ + DarkOrchid1 DarkOrchid2 DarkOrchid3 DarkOrchid4 purple1 \ + purple2 purple3 purple4 MediumPurple1 MediumPurple2 \ + MediumPurple3 MediumPurple4 thistle1 thistle2 thistle3 \ + thistle4 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/cscroll.tcl ./library/demos.jp/cscroll.tcl *** ../../tk8.0.5/library/demos.jp/cscroll.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/cscroll.tcl Thu Apr 1 00:08:28 1999 *************** *** 0 **** --- 1,98 ---- + # cscroll.tcl -- + # + # This demonstration script creates a simple canvas that can be + # scrolled in two dimensions. + # + # RCS: @(#) $Id: cscroll.tcl,v 1.1 1999/03/31 15:08:28 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .cscroll + catch {destroy $w} + toplevel $w + wm title $w "Scrollable Canvas Demonstration" + wm iconname $w "cscroll" + positionWindow $w + set c $w.c + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with button 2 in the canvas. If you click button 1 on one of the rectangles, its indices will be printed on stdout." \ + "$B$3$N%&%#%s%I%&$K$O%9%/%m!<%k%P!<$d%^%&%9$N%\%?%s(B2 $B$G%9%/%m!<%k$G$-$k%-%c%s%P%9(B widget $B$,I=<($5$l$F$$$^$9!#;M3Q$N>e$G%\%?%s(B1 $B$r%/%j%C%/$9$k$H!"$=$N%$%s%G%C%/%9$,I8=`=PNO$K=PNO$5$l$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.grid + scrollbar $w.hscroll -orient horiz -command "$c xview" + scrollbar $w.vscroll -command "$c yview" + canvas $c -relief sunken -borderwidth 2 -scrollregion {-11c -11c 50c 20c} \ + -xscrollcommand "$w.hscroll set" \ + -yscrollcommand "$w.vscroll set" + pack $w.grid -expand yes -fill both -padx 1 -pady 1 + grid rowconfig $w.grid 0 -weight 1 -minsize 0 + grid columnconfig $w.grid 0 -weight 1 -minsize 0 + + grid $c -padx 1 -in $w.grid -pady 1 \ + -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid $w.vscroll -in $w.grid -padx 1 -pady 1 \ + -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news + grid $w.hscroll -in $w.grid -padx 1 -pady 1 \ + -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news + + + set bg [lindex [$c config -bg] 4] + for {set i 0} {$i < 20} {incr i} { + set x [expr {-10 + 3*$i}] + for {set j 0; set y -10} {$j < 10} {incr j; incr y 3} { + $c create rect ${x}c ${y}c [expr $x+2]c [expr $y+2]c \ + -outline black -fill $bg -tags rect + $c create text [expr $x+1]c [expr $y+1]c -text "$i,$j" \ + -anchor center -tags text + } + } + + $c bind all "scrollEnter $c" + $c bind all "scrollLeave $c" + $c bind all <1> "scrollButton $c" + bind $c <2> "$c scan mark %x %y" + bind $c "$c scan dragto %x %y" + + proc scrollEnter canvas { + global oldFill + set id [$canvas find withtag current] + if {[lsearch [$canvas gettags current] text] >= 0} { + set id [expr $id-1] + } + set oldFill [lindex [$canvas itemconfig $id -fill] 4] + if {[winfo depth $canvas] > 1} { + $canvas itemconfigure $id -fill SeaGreen1 + } else { + $canvas itemconfigure $id -fill black + $canvas itemconfigure [expr $id+1] -fill white + } + } + + proc scrollLeave canvas { + global oldFill + set id [$canvas find withtag current] + if {[lsearch [$canvas gettags current] text] >= 0} { + set id [expr $id-1] + } + $canvas itemconfigure $id -fill $oldFill + $canvas itemconfigure [expr $id+1] -fill black + } + + proc scrollButton canvas { + global oldFill + set id [$canvas find withtag current] + if {[lsearch [$canvas gettags current] text] < 0} { + set id [expr $id+1] + } + puts stdout "You buttoned at [lindex [$canvas itemconf $id -text] 4]" + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/ctext.tcl ./library/demos.jp/ctext.tcl *** ../../tk8.0.5/library/demos.jp/ctext.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/ctext.tcl Mon May 10 19:10:21 1999 *************** *** 0 **** --- 1,177 ---- + # ctext.tcl -- + # + # This demonstration script creates a canvas widget with a text + # item that can be edited and reconfigured in various ways. + # + # RCS: @(#) $Id: ctext.tcl,v 1.2 1999/05/08 01:05:22 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .ctext + catch {destroy $w} + toplevel $w + wm title $w "Canvas Text Demonstration" + wm iconname $w "Text" + positionWindow $w + set c $w.c + + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "This window displays a string of text to demonstrate the text facilities of canvas widgets. You can click in the boxes to adjust the position of the text relative to its positioning point or change its justification. The text also supports the following simple bindings for editing: + 1. You can point, click, and type. + 2. You can also select with button 1. + 3. You can copy the selection to the mouse position with button 2. + 4. Backspace and Control+h delete the selection if there is one; + otherwise they delete the character just before the insertion cursor. + 5. Delete deletes the selection if there is one; otherwise it deletes + the character just after the insertion cursor." \ + "$B$3$N%&%#%s%I%&$K$O%-%c%s%P%9(B widget $B$N%F%-%9%H5!G=$r%G%b$9$k$?$a$N%F%-%9%HJ8;zNs$,I=<($5$l$F$$$^$9!#%^%&%9$r;M3Q$NCf$K;}$C$F$$$-!"%/%j%C%/$9$k$H0LCV$.$aMQ$NE@$+$i$NAjBP0LCV$rJQ$($?$j!"9TB7$($rJQ$($?$j$9$k$3$H$,$G$-$^$9!#$^$?0J2<$N$h$&$JJT=8$N$?$a$N4JC1$J%P%$%s%G%#%s%0$r%5%]!<%H$7$F$$$^$9!#(B + 1. $B%^%&%9$r;}$C$F$$$-!"%/%j%C%/$7!"F~NO$G$-$^$9!#(B + 2. $B%\%?%s(B 1 $B$GA*Br$G$-$^$9!#(B + 3. $B%^%&%9$N0LCV$K%\%?%s(B2 $B$GA*Br$7$?%F%-%9%H$r%3%T!<$G$-$^$9!#(B + 4. $B%P%C%/%9%Z!<%9$H%3%s%H%m!<%k(B-H $B$O!"$b$7A*BrNN0h$,$"$l$P$=$l$r:o=|$7!"$J$1$l$PA^F~%+!<%=%k$ND>A0$NJ8;z$r:o=|$7$^$9!#(B + 5. Delete $B%-!<$O!"$b$7A*BrNN0h$,$"$l$P$=$l$r:o=|$7!"$J$1$l$PA^F~%+!<%=%k$ND>8e$NJ8;z$r:o=|$7$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + canvas $c -relief flat -borderwidth 0 -width 500 -height 350 + pack $w.c -side top -expand yes -fill both + + set textFont {Helvetica 24} + + $c create rectangle 245 195 255 205 -outline black -fill red + + # First, create the text item and give it bindings so it can be edited. + + $c addtag text withtag [$c create text 250 200 -text [langSel \ + "This is just a string of text to demonstrate the text facilities of canvas widgets. Bindings have been been defined to support editing (see above)." \ + "$B$3$l$O%-%c%s%P%9(B widget $B$N%F%-%9%H5!G=$r%G%b$9$k$?$a$NJ8;zNs$G$9!#JT=8$r%5%]!<%H$9$k$?$a$K%-!<%P%$%s%G%#%s%0$,Dj5A$5$l$F$$$^$9(B($B>e5-;2>H(B)$B!#(B"] \ + -width 440 -anchor n -font {Helvetica24} -justify left] + $c bind text <1> "textB1Press $c %x %y" + $c bind text "textB1Move $c %x %y" + $c bind text "$c select adjust current @%x,%y" + $c bind text "textB1Move $c %x %y" + $c bind text "textInsert $c %A" + $c bind text "textInsert $c \\n" + $c bind text "textBs $c" + $c bind text "textBs $c" + $c bind text "textDel $c" + $c bind text <2> "textPaste $c @%x,%y" + if {[info commands kanji] != {} && $tcl_platform(platform) == "unix"} { + if {[info command tkInitializeIm] != {}} { + $c bind text "tkInitializeIm $c" + } elseif {[info command tkConfigIm] != {}} { + $c bind text "tkConfigIm $c" + } elseif {[info command kanjiInput] != {}} { + $c bind text "canvKanjiInput $c" + } + } + + # Canvas Kanji input via kinput protocol. + proc canvKinputTrace {name1 name2 op} { + upvar #0 $name1 trvar + textInsert $name2 $trvar($name2) + unset $trvar($name2) + } + proc canvKanjiInput {path} { + global canvKanjiInputData + trace variable canvKanjiInputData($path) w canvKinputTrace + kanjiInput start $path -variable canvKanjiInputData($path) -inputStyle root + } + + # Next, create some items that allow the text's anchor position + # to be edited. + + proc mkTextConfig {w x y option value color} { + set item [$w create rect [expr $x] [expr $y] [expr $x+30] [expr $y+30] \ + -outline black -fill $color -width 1] + $w bind $item <1> "$w itemconf text $option $value" + $w addtag config withtag $item + } + + set x 50 + set y 50 + set color LightSkyBlue1 + mkTextConfig $c $x $y -anchor se $color + mkTextConfig $c [expr $x+30] [expr $y] -anchor s $color + mkTextConfig $c [expr $x+60] [expr $y] -anchor sw $color + mkTextConfig $c [expr $x] [expr $y+30] -anchor e $color + mkTextConfig $c [expr $x+30] [expr $y+30] -anchor center $color + mkTextConfig $c [expr $x+60] [expr $y+30] -anchor w $color + mkTextConfig $c [expr $x] [expr $y+60] -anchor ne $color + mkTextConfig $c [expr $x+30] [expr $y+60] -anchor n $color + mkTextConfig $c [expr $x+60] [expr $y+60] -anchor nw $color + set item [$c create rect [expr $x+40] [expr $y+40] [expr $x+50] [expr $y+50] \ + -outline black -fill red] + $c bind $item <1> "$c itemconf text -anchor center" + $c create text [expr $x+45] [expr $y-5] -text {Text Position} -anchor s \ + -font {Times 24} -fill brown + + # Lastly, create some items that allow the text's justification to be + # changed. + + set x 350 + set y 50 + set color SeaGreen2 + mkTextConfig $c $x $y -justify left $color + mkTextConfig $c [expr $x+30] [expr $y] -justify center $color + mkTextConfig $c [expr $x+60] [expr $y] -justify right $color + $c create text [expr $x+45] [expr $y-5] -text {Justification} -anchor s \ + -font {Times 24} -fill brown + + $c bind config "textEnter $c" + $c bind config "$c itemconf current -fill \$textConfigFill" + + set textConfigFill {} + + proc textEnter {w} { + global textConfigFill + set textConfigFill [lindex [$w itemconfig current -fill] 4] + $w itemconfig current -fill black + } + + proc textInsert {w string} { + if {$string == ""} { + return + } + catch {$w dchars text sel.first sel.last} + $w insert text insert $string + } + + proc textPaste {w pos} { + catch { + $w insert text $pos [selection get] + } + } + + proc textB1Press {w x y} { + $w icursor current @$x,$y + $w focus current + focus $w + $w select from current @$x,$y + } + + proc textB1Move {w x y} { + $w select to current @$x,$y + } + + proc textBs {w} { + if ![catch {$w dchars text sel.first sel.last}] { + return + } + set char [expr {[$w index text insert] - 1}] + if {$char >= 0} {$w dchar text $char} + } + + proc textDel {w} { + if ![catch {$w dchars text sel.first sel.last}] { + return + } + $w dchars text insert + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/dialog1.tcl ./library/demos.jp/dialog1.tcl *** ../../tk8.0.5/library/demos.jp/dialog1.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/dialog1.tcl Thu Apr 1 00:08:28 1999 *************** *** 0 **** --- 1,17 ---- + # dialog1.tcl -- + # + # This demonstration script creates a dialog box with a local grab. + # + # RCS: @(#) $Id: dialog1.tcl,v 1.1 1999/03/31 15:08:28 m-hirano Exp $ + + after idle {.dialog1.msg configure -wraplength 4i} + set i [tk_dialog .dialog1 "Dialog with local grab" [langSel \ + {This is a modal dialog box. It uses Tk's "grab" command to create a "local grab" on the dialog box. The grab prevents any pointer-related events from getting to any other windows in the application until you have answered the dialog by invoking one of the buttons below. However, you can still interact with other applications.} \ + {$B%b!<%@%k%@%$%"%m%0%\%C%/%9$G$9!#(BTk $B$N(B "grab" $B%3%^%s%I$r;HMQ$7$F%@%$%"%m%0%\%C%/%9$G!V%m!<%+%k%0%i%V!W$7$F$$$^$9!#2<$N$$$:$l$+$N%\%?%s$r$N%&%#%s%I%&$G$O!"%]%$%s%?4X78$N%$%Y%s%H$rH(B}]] + + switch $i { + 0 {puts "You pressed OK"} + 1 {puts "You pressed Cancel"} + 2 {showCode .dialog1} + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/dialog2.tcl ./library/demos.jp/dialog2.tcl *** ../../tk8.0.5/library/demos.jp/dialog2.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/dialog2.tcl Thu Apr 1 00:08:29 1999 *************** *** 0 **** --- 1,22 ---- + # dialog2.tcl -- + # + # This demonstration script creates a dialog box with a global grab. + # + # RCS: @(#) $Id: dialog2.tcl,v 1.1 1999/03/31 15:08:29 m-hirano Exp $ + + after idle { + .dialog2.msg configure -wraplength 4i + } + after 100 { + grab -global .dialog2 + } + set i [tk_dialog .dialog2 "Dialog with local grab" [langSel \ + {This dialog box uses a global grab, so it prevents you from interacting with anything on your display until you invoke one of the buttons below. Global grabs are almost always a bad idea; don't use them unless you're truly desperate.} \ + {$B$3$N%@%$%"%m%0%\%C%/%9$O%0%m!<%P%k%0%i%V$r;HMQ$7$F$$$^$9!#2<$N%\%?%s$re$N$$$+$J$k$b$N$H$bBPOC$G$-$^$;$s!#%0%m!<%P%k%0%i%V$r;HMQ$9$k$3$H$O!"$^$:NI$$9M$($G$O$"$j$^$;$s!#$I$&$7$F$bI,MW$K$J$k$^$G;H$*$&$H;W$o$J$$$G2<$5$$!#(B}] \ + warning 0 [langSel OK $BN;2r(B] [langSel Cancel $B%-%c%s%;%k(B] [langSel {Show Code} {$B%3!<%I;2>H(B}]] + + switch $i { + 0 {puts "You pressed OK"} + 1 {puts "You pressed Cancel"} + 2 {showCode .dialog2} + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/entry1.tcl ./library/demos.jp/entry1.tcl *** ../../tk8.0.5/library/demos.jp/entry1.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/entry1.tcl Thu Apr 1 00:08:29 1999 *************** *** 0 **** --- 1,47 ---- + # entry1.tcl -- + # + # This demonstration script creates several entry widgets without + # scrollbars. + # + # RCS: @(#) $Id: entry1.tcl,v 1.1 1999/03/31 15:08:29 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .entry1 + catch {destroy $w} + toplevel $w + wm title $w "Entry Demonstration (no scrollbars)" + wm iconname $w "entry1" + positionWindow $w + + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "Three different entries are displayed below. You can add characters by pointing, clicking and typing. The normal Motif editing characters are supported, along with many Emacs bindings. For example, Backspace and Control-h delete the character to the left of the insertion cursor and Delete and Control-d delete the chararacter to the right of the insertion cursor. For entries that are too large to fit in the window all at once, you can scan through the entries by dragging with mouse button2 pressed." \ + [concat "3$BL>4A;zJQ49%U%m%s%H%(%s%I%W%m%;%C%5$rMQ$$$FF|K\8l$rF~NO$9$k$3$H$,$G$-$^$9!#JQ49%-!<$O(B X $B%j%=!<%9%G!<%?%Y!<%9$G;XDj$7$^$9!#(BWindows$BHG$G$O(B IME $B$r;H$C$F$=$N>lJQ49$GF|K\8l$rF~NO$9$k$3$H$,$G$-$^$9!#(B" ""]]] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + entry $w.e1 + entry $w.e2 + entry $w.e3 + pack $w.e1 $w.e2 $w.e3 -side top -pady 5 -padx 10 -fill x + + langSwitch { + $w.e1 insert 0 "Initial value" + $w.e2 insert end "This entry contains a long value, much too long " + $w.e2 insert end "to fit in the window at one time, so long in fact " + $w.e2 insert end "that you'll have to scan or scroll to see the end." + } { + $w.e1 insert 0 "$B=i4|CM(B" + $w.e2 insert end "$B$3$N%(%s%H%j$K$OD9$$J8;zNs$,F~$C$F$$$F!"(B" + $w.e2 insert end "$BD9$9$.$F%&%#%s%I%&$K$OF~$j@Z$i$J$$$N$G!"(B" + $w.e2 insert end "$BL>4A;zJQ49%U%m%s%H%(%s%I%W%m%;%C%5$rMQ$$$FF|K\8l$rF~NO$9$k$3$H$,$G$-$^$9!#JQ49%-!<$O(B X $B%j%=!<%9%G!<%?%Y!<%9$G;XDj$7$^$9!#(BWindows$BHG$G$O(B IME $B$r;H$C$F$=$N>lJQ49$GF|K\8l$rF~NO$9$k$3$H$,$G$-$^$9!#(B" ""]]] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame -borderwidth 10 + pack $w.frame -side top -fill x -expand 1 + + entry $w.frame.e1 -xscrollcommand "$w.frame.s1 set" + scrollbar $w.frame.s1 -relief sunken -orient horiz -command \ + "$w.frame.e1 xview" + frame $w.frame.spacer1 -width 20 -height 10 + entry $w.frame.e2 -xscrollcommand "$w.frame.s2 set" + scrollbar $w.frame.s2 -relief sunken -orient horiz -command \ + "$w.frame.e2 xview" + frame $w.frame.spacer2 -width 20 -height 10 + entry $w.frame.e3 -xscrollcommand "$w.frame.s3 set" + scrollbar $w.frame.s3 -relief sunken -orient horiz -command \ + "$w.frame.e3 xview" + pack $w.frame.e1 $w.frame.s1 $w.frame.spacer1 $w.frame.e2 $w.frame.s2 \ + $w.frame.spacer2 $w.frame.e3 $w.frame.s3 -side top -fill x + + langSwitch { + $w.frame.e1 insert 0 "Initial value" + $w.frame.e2 insert end "This entry contains a long value, much too long " + $w.frame.e2 insert end "to fit in the window at one time, so long in fact " + $w.frame.e2 insert end "that you'll have to scan or scroll to see the end." + } { + $w.frame.e1 insert 0 "$B=i4|CM(B" + $w.frame.e2 insert end "$B$3$N%(%s%H%j$K$OD9$$J8;zNs$,F~$C$F$$$F!"(B" + $w.frame.e2 insert end "$BD9$9$.$F%&%#%s%I%&$K$OF~$j@Z$i$J$$$N$G!"(B" + $w.frame.e2 insert end "$B$rF~NO$9$k$+!"(B\"$BA*Br(B\"$B%\%?%s$r2!$7$F%U%!%$%kA*Br%@%$%"%m%0$G%U%!%$%kL>$rA*Br$7$F$/$@$5$$!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + foreach i {open save} { + set f [frame $w.$i] + label $f.lab -text [langSel \ + "Select a file to $i: " \ + [if {$i == "open"} {concat "$B3+$/%U%!%$%k(B: "} else {concat "$BJ]B8$9$k%U%!%$%k(B: "}]] \ + -anchor e + entry $f.ent -width 20 + button $f.but -text [langSel "Browse ..." "$BA*Br(B ..."] -command "fileDialog $w $f.ent $i" + pack $f.lab -side left + pack $f.ent -side left -expand yes -fill x + pack $f.but -side left + pack $f -fill x -padx 1c -pady 3 + } + + if ![string compare $tcl_platform(platform) unix] { + checkbutton $w.strict -text [langSel "Use Motif Style Dialog" "Motif $BIw%@%$%"%m%0$r;HMQ(B"] \ + -variable tk_strictMotif -onvalue 1 -offvalue 0 + pack $w.strict -anchor c + } + + proc fileDialog {w ent operation} { + # Type names Extension(s) Mac File Type(s) + # + #--------------------------------------------------------- + set types [langSel { + {"Text files" {.txt .doc} } + {"Text files" {} TEXT} + {"Tcl Scripts" {.tcl} TEXT} + {"C Source Files" {.c .h} } + {"All Source Files" {.tcl .c .h} } + {"Image Files" {.gif} } + {"Image Files" {.jpeg .jpg} } + {"Image Files" "" {GIFF JPEG}} + {"All files" *} + } { + {"$B%F%-%9%H%U%!%$%k(B" {.txt .doc} } + {"$B%F%-%9%H%U%!%$%k(B" {} TEXT} + {"Tcl $B%9%/%j%W%H(B" {.tcl} TEXT} + {"C $B%=!<%9%U%!%$%k(B" {.c .h} } + {"$BA4$F$N%=!<%9%U%!%$%k(B" {.tcl .c .h} } + {"$B2hA|%U%!%$%k(B" {.gif} } + {"$B2hA|%U%!%$%k(B" {.jpeg .jpg} } + {"$B2hA|%U%!%$%k(B" "" {GIFF JPEG}} + {"$BA4$F$N%U%!%$%k(B" *} + }] + if {$operation == "open"} { + set file [tk_getOpenFile -filetypes $types -parent $w] + } else { + set file [tk_getSaveFile -filetypes $types -parent $w \ + -initialfile Untitled -defaultextension .txt] + } + if [string compare $file ""] { + $ent delete 0 end + $ent insert 0 $file + $ent xview end + } + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/floor.tcl ./library/demos.jp/floor.tcl *** ../../tk8.0.5/library/demos.jp/floor.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/floor.tcl Thu Apr 1 00:08:30 1999 *************** *** 0 **** --- 1,1372 ---- + # floor.tcl -- + # + # This demonstration script creates a canvas widet that displays the + # floorplan for DEC's Western Research Laboratory. + # + # RCS: @(#) $Id: floor.tcl,v 1.1 1999/03/31 15:08:30 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # floorDisplay -- + # Recreate the floorplan display in the canvas given by "w". The + # floor given by "active" is displayed on top with its office structure + # visible. + # + # Arguments: + # w - Name of the canvas window. + # active - Number of active floor (1, 2, or 3). + + proc floorDisplay {w active} { + global floorLabels floorItems colors activeFloor + + if {$activeFloor == $active} { + return + } + + $w delete all + set activeFloor $active + + # First go through the three floors, displaying the backgrounds for + # each floor. + + bg1 $w $colors(bg1) $colors(outline1) + bg2 $w $colors(bg2) $colors(outline2) + bg3 $w $colors(bg3) $colors(outline3) + + # Raise the background for the active floor so that it's on top. + + $w raise floor$active + + # Create a dummy item just to mark this point in the display list, + # so we can insert highlights here. + + $w create rect 0 100 1 101 -fill {} -outline {} -tags marker + + # Add the walls and labels for the active floor, along with + # transparent polygons that define the rooms on the floor. + # Make sure that the room polygons are on top. + + catch {unset floorLabels} + catch {unset floorItems} + fg$active $w $colors(offices) + $w raise room + + # Offset the floors diagonally from each other. + + $w move floor1 2c 2c + $w move floor2 1c 1c + + # Create items for the room entry and its label. + + $w create window 600 100 -anchor w -window $w.entry + $w create text 600 100 -anchor e -text [langSel "Room: " "$BIt20HV9f(B: "] + $w config -scrollregion [$w bbox all] + } + + # newRoom -- + # This procedure is invoked whenever the mouse enters a room + # in the floorplan. It changes tags so that the current room is + # highlighted. + # + # Arguments: + # w - The name of the canvas window. + + proc newRoom w { + global currentRoom floorLabels + + set id [$w find withtag current] + if {$id != ""} { + set currentRoom $floorLabels($id) + } + update idletasks + } + + # roomChanged -- + # This procedure is invoked whenever the currentRoom variable changes. + # It highlights the current room and unhighlights any previous room. + # + # Arguments: + # w - The canvas window displaying the floorplan. + # args - Not used. + + proc roomChanged {w args} { + global currentRoom floorItems colors + $w delete highlight + if [catch {set item $floorItems($currentRoom)}] { + return + } + set new [eval \ + "$w create polygon [$w coords $item] -fill $colors(active) \ + -tags highlight"] + $w raise $new marker + } + + # bg1 -- + # This procedure represents part of the floorplan database. When + # invoked, it instantiates the background information for the first + # floor. + # + # Arguments: + # w - The canvas window. + # fill - Fill color to use for the floor's background. + # outline - Color to use for the floor's outline. + + proc bg1 {w fill outline} { + $w create poly 347 80 349 82 351 84 353 85 363 92 375 99 386 104 \ + 386 129 398 129 398 162 484 162 484 129 559 129 559 133 725 \ + 133 725 129 802 129 802 389 644 389 644 391 559 391 559 327 \ + 508 327 508 311 484 311 484 278 395 278 395 288 400 288 404 \ + 288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 \ + 411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 \ + 342 331 347 332 351 334 354 336 357 341 359 340 360 335 363 \ + 331 365 326 366 304 366 304 355 258 355 258 387 60 387 60 391 \ + 0 391 0 337 3 337 3 114 8 114 8 25 30 25 30 5 93 5 98 5 104 7 \ + 110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 34 221 \ + 22 223 17 227 13 231 8 236 4 242 2 246 0 260 0 283 1 300 5 \ + 321 14 335 22 348 25 365 29 363 39 358 48 352 56 337 70 \ + 344 76 347 80 \ + -tags {floor1 bg} -fill $fill + $w create line 386 129 398 129 -fill $outline -tags {floor1 bg} + $w create line 258 355 258 387 -fill $outline -tags {floor1 bg} + $w create line 60 387 60 391 -fill $outline -tags {floor1 bg} + $w create line 0 337 0 391 -fill $outline -tags {floor1 bg} + $w create line 60 391 0 391 -fill $outline -tags {floor1 bg} + $w create line 3 114 3 337 -fill $outline -tags {floor1 bg} + $w create line 258 387 60 387 -fill $outline -tags {floor1 bg} + $w create line 484 162 398 162 -fill $outline -tags {floor1 bg} + $w create line 398 162 398 129 -fill $outline -tags {floor1 bg} + $w create line 484 278 484 311 -fill $outline -tags {floor1 bg} + $w create line 484 311 508 311 -fill $outline -tags {floor1 bg} + $w create line 508 327 508 311 -fill $outline -tags {floor1 bg} + $w create line 559 327 508 327 -fill $outline -tags {floor1 bg} + $w create line 644 391 559 391 -fill $outline -tags {floor1 bg} + $w create line 644 389 644 391 -fill $outline -tags {floor1 bg} + $w create line 559 129 484 129 -fill $outline -tags {floor1 bg} + $w create line 484 162 484 129 -fill $outline -tags {floor1 bg} + $w create line 725 133 559 133 -fill $outline -tags {floor1 bg} + $w create line 559 129 559 133 -fill $outline -tags {floor1 bg} + $w create line 725 129 802 129 -fill $outline -tags {floor1 bg} + $w create line 802 389 802 129 -fill $outline -tags {floor1 bg} + $w create line 3 337 0 337 -fill $outline -tags {floor1 bg} + $w create line 559 391 559 327 -fill $outline -tags {floor1 bg} + $w create line 802 389 644 389 -fill $outline -tags {floor1 bg} + $w create line 725 133 725 129 -fill $outline -tags {floor1 bg} + $w create line 8 25 8 114 -fill $outline -tags {floor1 bg} + $w create line 8 114 3 114 -fill $outline -tags {floor1 bg} + $w create line 30 25 8 25 -fill $outline -tags {floor1 bg} + $w create line 484 278 395 278 -fill $outline -tags {floor1 bg} + $w create line 30 25 30 5 -fill $outline -tags {floor1 bg} + $w create line 93 5 30 5 -fill $outline -tags {floor1 bg} + $w create line 98 5 93 5 -fill $outline -tags {floor1 bg} + $w create line 104 7 98 5 -fill $outline -tags {floor1 bg} + $w create line 110 10 104 7 -fill $outline -tags {floor1 bg} + $w create line 116 16 110 10 -fill $outline -tags {floor1 bg} + $w create line 119 20 116 16 -fill $outline -tags {floor1 bg} + $w create line 122 28 119 20 -fill $outline -tags {floor1 bg} + $w create line 123 32 122 28 -fill $outline -tags {floor1 bg} + $w create line 123 68 123 32 -fill $outline -tags {floor1 bg} + $w create line 220 68 123 68 -fill $outline -tags {floor1 bg} + $w create line 386 129 386 104 -fill $outline -tags {floor1 bg} + $w create line 386 104 375 99 -fill $outline -tags {floor1 bg} + $w create line 375 99 363 92 -fill $outline -tags {floor1 bg} + $w create line 353 85 363 92 -fill $outline -tags {floor1 bg} + $w create line 220 68 220 34 -fill $outline -tags {floor1 bg} + $w create line 337 70 352 56 -fill $outline -tags {floor1 bg} + $w create line 352 56 358 48 -fill $outline -tags {floor1 bg} + $w create line 358 48 363 39 -fill $outline -tags {floor1 bg} + $w create line 363 39 365 29 -fill $outline -tags {floor1 bg} + $w create line 365 29 348 25 -fill $outline -tags {floor1 bg} + $w create line 348 25 335 22 -fill $outline -tags {floor1 bg} + $w create line 335 22 321 14 -fill $outline -tags {floor1 bg} + $w create line 321 14 300 5 -fill $outline -tags {floor1 bg} + $w create line 300 5 283 1 -fill $outline -tags {floor1 bg} + $w create line 283 1 260 0 -fill $outline -tags {floor1 bg} + $w create line 260 0 246 0 -fill $outline -tags {floor1 bg} + $w create line 246 0 242 2 -fill $outline -tags {floor1 bg} + $w create line 242 2 236 4 -fill $outline -tags {floor1 bg} + $w create line 236 4 231 8 -fill $outline -tags {floor1 bg} + $w create line 231 8 227 13 -fill $outline -tags {floor1 bg} + $w create line 223 17 227 13 -fill $outline -tags {floor1 bg} + $w create line 221 22 223 17 -fill $outline -tags {floor1 bg} + $w create line 220 34 221 22 -fill $outline -tags {floor1 bg} + $w create line 340 360 335 363 -fill $outline -tags {floor1 bg} + $w create line 335 363 331 365 -fill $outline -tags {floor1 bg} + $w create line 331 365 326 366 -fill $outline -tags {floor1 bg} + $w create line 326 366 304 366 -fill $outline -tags {floor1 bg} + $w create line 304 355 304 366 -fill $outline -tags {floor1 bg} + $w create line 395 288 400 288 -fill $outline -tags {floor1 bg} + $w create line 404 288 400 288 -fill $outline -tags {floor1 bg} + $w create line 409 290 404 288 -fill $outline -tags {floor1 bg} + $w create line 413 292 409 290 -fill $outline -tags {floor1 bg} + $w create line 418 297 413 292 -fill $outline -tags {floor1 bg} + $w create line 421 302 418 297 -fill $outline -tags {floor1 bg} + $w create line 422 309 421 302 -fill $outline -tags {floor1 bg} + $w create line 421 318 422 309 -fill $outline -tags {floor1 bg} + $w create line 421 318 417 325 -fill $outline -tags {floor1 bg} + $w create line 417 325 411 330 -fill $outline -tags {floor1 bg} + $w create line 411 330 405 332 -fill $outline -tags {floor1 bg} + $w create line 405 332 397 333 -fill $outline -tags {floor1 bg} + $w create line 397 333 344 333 -fill $outline -tags {floor1 bg} + $w create line 344 333 340 334 -fill $outline -tags {floor1 bg} + $w create line 340 334 336 336 -fill $outline -tags {floor1 bg} + $w create line 336 336 335 338 -fill $outline -tags {floor1 bg} + $w create line 335 338 332 342 -fill $outline -tags {floor1 bg} + $w create line 331 347 332 342 -fill $outline -tags {floor1 bg} + $w create line 332 351 331 347 -fill $outline -tags {floor1 bg} + $w create line 334 354 332 351 -fill $outline -tags {floor1 bg} + $w create line 336 357 334 354 -fill $outline -tags {floor1 bg} + $w create line 341 359 336 357 -fill $outline -tags {floor1 bg} + $w create line 341 359 340 360 -fill $outline -tags {floor1 bg} + $w create line 395 288 395 278 -fill $outline -tags {floor1 bg} + $w create line 304 355 258 355 -fill $outline -tags {floor1 bg} + $w create line 347 80 344 76 -fill $outline -tags {floor1 bg} + $w create line 344 76 337 70 -fill $outline -tags {floor1 bg} + $w create line 349 82 347 80 -fill $outline -tags {floor1 bg} + $w create line 351 84 349 82 -fill $outline -tags {floor1 bg} + $w create line 353 85 351 84 -fill $outline -tags {floor1 bg} + } + + # bg2 -- + # This procedure represents part of the floorplan database. When + # invoked, it instantiates the background information for the second + # floor. + # + # Arguments: + # w - The canvas window. + # fill - Fill color to use for the floor's background. + # outline - Color to use for the floor's outline. + + proc bg2 {w fill outline} { + $w create poly 559 129 484 129 484 162 398 162 398 129 315 129 \ + 315 133 176 133 176 129 96 129 96 133 3 133 3 339 0 339 0 391 \ + 60 391 60 387 258 387 258 329 350 329 350 311 395 311 395 280 \ + 484 280 484 311 508 311 508 327 558 327 558 391 644 391 644 \ + 367 802 367 802 129 725 129 725 133 559 133 559 129 \ + -tags {floor2 bg} -fill $fill + $w create line 350 311 350 329 -fill $outline -tags {floor2 bg} + $w create line 398 129 398 162 -fill $outline -tags {floor2 bg} + $w create line 802 367 802 129 -fill $outline -tags {floor2 bg} + $w create line 802 129 725 129 -fill $outline -tags {floor2 bg} + $w create line 725 133 725 129 -fill $outline -tags {floor2 bg} + $w create line 559 129 559 133 -fill $outline -tags {floor2 bg} + $w create line 559 133 725 133 -fill $outline -tags {floor2 bg} + $w create line 484 162 484 129 -fill $outline -tags {floor2 bg} + $w create line 559 129 484 129 -fill $outline -tags {floor2 bg} + $w create line 802 367 644 367 -fill $outline -tags {floor2 bg} + $w create line 644 367 644 391 -fill $outline -tags {floor2 bg} + $w create line 644 391 558 391 -fill $outline -tags {floor2 bg} + $w create line 558 327 558 391 -fill $outline -tags {floor2 bg} + $w create line 558 327 508 327 -fill $outline -tags {floor2 bg} + $w create line 508 327 508 311 -fill $outline -tags {floor2 bg} + $w create line 484 311 508 311 -fill $outline -tags {floor2 bg} + $w create line 484 280 484 311 -fill $outline -tags {floor2 bg} + $w create line 398 162 484 162 -fill $outline -tags {floor2 bg} + $w create line 484 280 395 280 -fill $outline -tags {floor2 bg} + $w create line 395 280 395 311 -fill $outline -tags {floor2 bg} + $w create line 258 387 60 387 -fill $outline -tags {floor2 bg} + $w create line 3 133 3 339 -fill $outline -tags {floor2 bg} + $w create line 3 339 0 339 -fill $outline -tags {floor2 bg} + $w create line 60 391 0 391 -fill $outline -tags {floor2 bg} + $w create line 0 339 0 391 -fill $outline -tags {floor2 bg} + $w create line 60 387 60 391 -fill $outline -tags {floor2 bg} + $w create line 258 329 258 387 -fill $outline -tags {floor2 bg} + $w create line 350 329 258 329 -fill $outline -tags {floor2 bg} + $w create line 395 311 350 311 -fill $outline -tags {floor2 bg} + $w create line 398 129 315 129 -fill $outline -tags {floor2 bg} + $w create line 176 133 315 133 -fill $outline -tags {floor2 bg} + $w create line 176 129 96 129 -fill $outline -tags {floor2 bg} + $w create line 3 133 96 133 -fill $outline -tags {floor2 bg} + $w create line 315 133 315 129 -fill $outline -tags {floor2 bg} + $w create line 176 133 176 129 -fill $outline -tags {floor2 bg} + $w create line 96 133 96 129 -fill $outline -tags {floor2 bg} + } + + # bg3 -- + # This procedure represents part of the floorplan database. When + # invoked, it instantiates the background information for the third + # floor. + # + # Arguments: + # w - The canvas window. + # fill - Fill color to use for the floor's background. + # outline - Color to use for the floor's outline. + + proc bg3 {w fill outline} { + $w create poly 159 300 107 300 107 248 159 248 159 129 96 129 96 \ + 133 21 133 21 331 0 331 0 391 60 391 60 370 159 370 159 300 \ + -tags {floor3 bg} -fill $fill + $w create poly 258 370 258 329 350 329 350 311 399 311 399 129 \ + 315 129 315 133 176 133 176 129 159 129 159 370 258 370 \ + -tags {floor3 bg} -fill $fill + $w create line 96 133 96 129 -fill $outline -tags {floor3 bg} + $w create line 176 129 96 129 -fill $outline -tags {floor3 bg} + $w create line 176 129 176 133 -fill $outline -tags {floor3 bg} + $w create line 315 133 176 133 -fill $outline -tags {floor3 bg} + $w create line 315 133 315 129 -fill $outline -tags {floor3 bg} + $w create line 399 129 315 129 -fill $outline -tags {floor3 bg} + $w create line 399 311 399 129 -fill $outline -tags {floor3 bg} + $w create line 399 311 350 311 -fill $outline -tags {floor3 bg} + $w create line 350 329 350 311 -fill $outline -tags {floor3 bg} + $w create line 350 329 258 329 -fill $outline -tags {floor3 bg} + $w create line 258 370 258 329 -fill $outline -tags {floor3 bg} + $w create line 60 370 258 370 -fill $outline -tags {floor3 bg} + $w create line 60 370 60 391 -fill $outline -tags {floor3 bg} + $w create line 60 391 0 391 -fill $outline -tags {floor3 bg} + $w create line 0 391 0 331 -fill $outline -tags {floor3 bg} + $w create line 21 331 0 331 -fill $outline -tags {floor3 bg} + $w create line 21 331 21 133 -fill $outline -tags {floor3 bg} + $w create line 96 133 21 133 -fill $outline -tags {floor3 bg} + $w create line 107 300 159 300 159 248 107 248 107 300 \ + -fill $outline -tags {floor3 bg} + } + + # fg1 -- + # This procedure represents part of the floorplan database. When + # invoked, it instantiates the foreground information for the first + # floor (office outlines and numbers). + # + # Arguments: + # w - The canvas window. + # color - Color to use for drawing foreground information. + + proc fg1 {w color} { + global floorLabels floorItems + set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -tags {floor1 room}] + set floorLabels($i) 101 + set {floorItems(101)} $i + $w create text 358 209 -text 101 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -tags {floor1 room}] + set floorLabels($i) {Pub Lift1} + set {floorItems(Pub Lift1)} $i + $w create text 323 223 -text {Pub Lift1} -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -tags {floor1 room}] + set floorLabels($i) {Priv Lift1} + set {floorItems(Priv Lift1)} $i + $w create text 323 188 -text {Priv Lift1} -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 42 389 42 337 1 337 1 389 -fill {} -tags {floor1 room}] + set floorLabels($i) 110 + set {floorItems(110)} $i + $w create text 21.5 363 -text 110 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 59 389 59 385 90 385 90 337 44 337 44 389 -fill {} -tags {floor1 room}] + set floorLabels($i) 109 + set {floorItems(109)} $i + $w create text 67 363 -text 109 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 51 300 51 253 6 253 6 300 -fill {} -tags {floor1 room}] + set floorLabels($i) 111 + set {floorItems(111)} $i + $w create text 28.5 276.5 -text 111 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 98 248 98 309 79 309 79 248 -fill {} -tags {floor1 room}] + set floorLabels($i) 117B + set {floorItems(117B)} $i + $w create text 88.5 278.5 -text 117B -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 51 251 51 204 6 204 6 251 -fill {} -tags {floor1 room}] + set floorLabels($i) 112 + set {floorItems(112)} $i + $w create text 28.5 227.5 -text 112 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 6 156 51 156 51 203 6 203 -fill {} -tags {floor1 room}] + set floorLabels($i) 113 + set {floorItems(113)} $i + $w create text 28.5 179.5 -text 113 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 85 169 79 169 79 192 85 192 -fill {} -tags {floor1 room}] + set floorLabels($i) 117A + set {floorItems(117A)} $i + $w create text 82 180.5 -text 117A -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 77 302 77 168 53 168 53 302 -fill {} -tags {floor1 room}] + set floorLabels($i) 117 + set {floorItems(117)} $i + $w create text 65 235 -text 117 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 51 155 51 115 6 115 6 155 -fill {} -tags {floor1 room}] + set floorLabels($i) 114 + set {floorItems(114)} $i + $w create text 28.5 135 -text 114 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 95 115 53 115 53 168 95 168 -fill {} -tags {floor1 room}] + set floorLabels($i) 115 + set {floorItems(115)} $i + $w create text 74 141.5 -text 115 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 87 113 87 27 10 27 10 113 -fill {} -tags {floor1 room}] + set floorLabels($i) 116 + set {floorItems(116)} $i + $w create text 48.5 70 -text 116 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 89 91 128 91 128 113 89 113 -fill {} -tags {floor1 room}] + set floorLabels($i) 118 + set {floorItems(118)} $i + $w create text 108.5 102 -text 118 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 178 128 178 132 216 132 216 91 163 91 163 112 149 112 149 128 -fill {} -tags {floor1 room}] + set floorLabels($i) 120 + set {floorItems(120)} $i + $w create text 189.5 111.5 -text 120 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 79 193 87 193 87 169 136 169 136 192 156 192 156 169 175 169 175 246 79 246 -fill {} -tags {floor1 room}] + set floorLabels($i) 122 + set {floorItems(122)} $i + $w create text 131 207.5 -text 122 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 138 169 154 169 154 191 138 191 -fill {} -tags {floor1 room}] + set floorLabels($i) 121 + set {floorItems(121)} $i + $w create text 146 180 -text 121 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 99 300 126 300 126 309 99 309 -fill {} -tags {floor1 room}] + set floorLabels($i) 106A + set {floorItems(106A)} $i + $w create text 112.5 304.5 -text 106A -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 128 299 128 309 150 309 150 248 99 248 99 299 -fill {} -tags {floor1 room}] + set floorLabels($i) 105 + set {floorItems(105)} $i + $w create text 124.5 278.5 -text 105 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 174 309 174 300 152 300 152 309 -fill {} -tags {floor1 room}] + set floorLabels($i) 106B + set {floorItems(106B)} $i + $w create text 163 304.5 -text 106B -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 176 299 176 309 216 309 216 248 152 248 152 299 -fill {} -tags {floor1 room}] + set floorLabels($i) 104 + set {floorItems(104)} $i + $w create text 184 278.5 -text 104 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 138 385 138 337 91 337 91 385 -fill {} -tags {floor1 room}] + set floorLabels($i) 108 + set {floorItems(108)} $i + $w create text 114.5 361 -text 108 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 256 337 140 337 140 385 256 385 -fill {} -tags {floor1 room}] + set floorLabels($i) 107 + set {floorItems(107)} $i + $w create text 198 361 -text 107 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 300 353 300 329 260 329 260 353 -fill {} -tags {floor1 room}] + set floorLabels($i) Smoking + set {floorItems(Smoking)} $i + $w create text 280 341 -text Smoking -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 314 135 314 170 306 170 306 246 177 246 177 135 -fill {} -tags {floor1 room}] + set floorLabels($i) 123 + set {floorItems(123)} $i + $w create text 245.5 190.5 -text 123 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 217 248 301 248 301 326 257 326 257 310 217 310 -fill {} -tags {floor1 room}] + set floorLabels($i) 103 + set {floorItems(103)} $i + $w create text 259 287 -text 103 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 396 188 377 188 377 169 316 169 316 131 396 131 -fill {} -tags {floor1 room}] + set floorLabels($i) 124 + set {floorItems(124)} $i + $w create text 356 150 -text 124 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 397 226 407 226 407 189 377 189 377 246 397 246 -fill {} -tags {floor1 room}] + set floorLabels($i) 125 + set {floorItems(125)} $i + $w create text 392 217.5 -text 125 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 399 187 409 187 409 207 474 207 474 164 399 164 -fill {} -tags {floor1 room}] + set floorLabels($i) 126 + set {floorItems(126)} $i + $w create text 436.5 185.5 -text 126 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 409 209 409 229 399 229 399 253 486 253 486 239 474 239 474 209 -fill {} -tags {floor1 room}] + set floorLabels($i) 127 + set {floorItems(127)} $i + $w create text 436.5 231 -text 127 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 501 164 501 174 495 174 495 188 490 188 490 204 476 204 476 164 -fill {} -tags {floor1 room}] + set floorLabels($i) MShower + set {floorItems(MShower)} $i + $w create text 488.5 184 -text MShower -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 497 176 513 176 513 204 492 204 492 190 497 190 -fill {} -tags {floor1 room}] + set floorLabels($i) Closet + set {floorItems(Closet)} $i + $w create text 502.5 190 -text Closet -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 476 237 476 206 513 206 513 254 488 254 488 237 -fill {} -tags {floor1 room}] + set floorLabels($i) WShower + set {floorItems(WShower)} $i + $w create text 494.5 230 -text WShower -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 486 131 558 131 558 135 724 135 724 166 697 166 697 275 553 275 531 254 515 254 515 174 503 174 503 161 486 161 -fill {} -tags {floor1 room}] + set floorLabels($i) 130 + set {floorItems(130)} $i + $w create text 638.5 205 -text 130 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 308 242 339 242 339 248 342 248 342 246 397 246 397 276 393 276 393 309 300 309 300 248 308 248 -fill {} -tags {floor1 room}] + set floorLabels($i) 102 + set {floorItems(102)} $i + $w create text 367.5 278.5 -text 102 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 397 255 486 255 486 276 397 276 -fill {} -tags {floor1 room}] + set floorLabels($i) 128 + set {floorItems(128)} $i + $w create text 441.5 265.5 -text 128 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 510 309 486 309 486 255 530 255 552 277 561 277 561 325 510 325 -fill {} -tags {floor1 room}] + set floorLabels($i) 129 + set {floorItems(129)} $i + $w create text 535.5 293 -text 129 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 696 281 740 281 740 387 642 387 642 389 561 389 561 277 696 277 -fill {} -tags {floor1 room}] + set floorLabels($i) 133 + set {floorItems(133)} $i + $w create text 628.5 335 -text 133 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 742 387 742 281 800 281 800 387 -fill {} -tags {floor1 room}] + set floorLabels($i) 132 + set {floorItems(132)} $i + $w create text 771 334 -text 132 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 800 168 800 280 699 280 699 168 -fill {} -tags {floor1 room}] + set floorLabels($i) 134 + set {floorItems(134)} $i + $w create text 749.5 224 -text 134 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 726 131 726 166 800 166 800 131 -fill {} -tags {floor1 room}] + set floorLabels($i) 135 + set {floorItems(135)} $i + $w create text 763 148.5 -text 135 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 340 360 335 363 331 365 326 366 304 366 304 312 396 312 396 288 400 288 404 288 409 290 413 292 418 297 421 302 422 309 421 318 417 325 411 330 405 332 397 333 344 333 340 334 336 336 335 338 332 342 331 347 332 351 334 354 336 357 341 359 -fill {} -tags {floor1 room}] + set floorLabels($i) {Ramona Stair} + set {floorItems(Ramona Stair)} $i + $w create text 368 323 -text {Ramona Stair} -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 30 23 30 5 93 5 98 5 104 7 110 10 116 16 119 20 122 28 123 32 123 68 220 68 220 87 90 87 90 23 -fill {} -tags {floor1 room}] + set floorLabels($i) {University Stair} + set {floorItems(University Stair)} $i + $w create text 155 77.5 -text {University Stair} -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 282 37 295 40 312 49 323 56 337 70 352 56 358 48 363 39 365 29 348 25 335 22 321 14 300 5 283 1 260 0 246 0 242 2 236 4 231 8 227 13 223 17 221 22 220 34 260 34 -fill {} -tags {floor1 room}] + set floorLabels($i) {Plaza Stair} + set {floorItems(Plaza Stair)} $i + $w create text 317.5 28.5 -text {Plaza Stair} -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 220 34 260 34 282 37 295 40 312 49 323 56 337 70 350 83 365 94 377 100 386 104 386 128 220 128 -fill {} -tags {floor1 room}] + set floorLabels($i) {Plaza Deck} + set {floorItems(Plaza Deck)} $i + $w create text 303 81 -text {Plaza Deck} -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 257 336 77 336 6 336 6 301 77 301 77 310 257 310 -fill {} -tags {floor1 room}] + set floorLabels($i) 106 + set {floorItems(106)} $i + $w create text 131.5 318.5 -text 106 -fill $color -anchor c -tags {floor1 label} + set i [$w create polygon 146 110 162 110 162 91 130 91 130 115 95 115 95 128 114 128 114 151 157 151 157 153 112 153 112 130 97 130 97 168 175 168 175 131 146 131 -fill {} -tags {floor1 room}] + set floorLabels($i) 119 + set {floorItems(119)} $i + $w create text 143.5 133 -text 119 -fill $color -anchor c -tags {floor1 label} + $w create line 155 191 155 189 -fill $color -tags {floor1 wall} + $w create line 155 177 155 169 -fill $color -tags {floor1 wall} + $w create line 96 129 96 169 -fill $color -tags {floor1 wall} + $w create line 78 169 176 169 -fill $color -tags {floor1 wall} + $w create line 176 247 176 129 -fill $color -tags {floor1 wall} + $w create line 340 206 307 206 -fill $color -tags {floor1 wall} + $w create line 340 187 340 170 -fill $color -tags {floor1 wall} + $w create line 340 210 340 201 -fill $color -tags {floor1 wall} + $w create line 340 247 340 224 -fill $color -tags {floor1 wall} + $w create line 340 241 307 241 -fill $color -tags {floor1 wall} + $w create line 376 246 376 170 -fill $color -tags {floor1 wall} + $w create line 307 247 307 170 -fill $color -tags {floor1 wall} + $w create line 376 170 307 170 -fill $color -tags {floor1 wall} + $w create line 315 129 315 170 -fill $color -tags {floor1 wall} + $w create line 147 129 176 129 -fill $color -tags {floor1 wall} + $w create line 202 133 176 133 -fill $color -tags {floor1 wall} + $w create line 398 129 315 129 -fill $color -tags {floor1 wall} + $w create line 258 352 258 387 -fill $color -tags {floor1 wall} + $w create line 60 387 60 391 -fill $color -tags {floor1 wall} + $w create line 0 337 0 391 -fill $color -tags {floor1 wall} + $w create line 60 391 0 391 -fill $color -tags {floor1 wall} + $w create line 3 114 3 337 -fill $color -tags {floor1 wall} + $w create line 258 387 60 387 -fill $color -tags {floor1 wall} + $w create line 52 237 52 273 -fill $color -tags {floor1 wall} + $w create line 52 189 52 225 -fill $color -tags {floor1 wall} + $w create line 52 140 52 177 -fill $color -tags {floor1 wall} + $w create line 395 306 395 311 -fill $color -tags {floor1 wall} + $w create line 531 254 398 254 -fill $color -tags {floor1 wall} + $w create line 475 178 475 238 -fill $color -tags {floor1 wall} + $w create line 502 162 398 162 -fill $color -tags {floor1 wall} + $w create line 398 129 398 188 -fill $color -tags {floor1 wall} + $w create line 383 188 376 188 -fill $color -tags {floor1 wall} + $w create line 408 188 408 194 -fill $color -tags {floor1 wall} + $w create line 398 227 398 254 -fill $color -tags {floor1 wall} + $w create line 408 227 398 227 -fill $color -tags {floor1 wall} + $w create line 408 222 408 227 -fill $color -tags {floor1 wall} + $w create line 408 206 408 210 -fill $color -tags {floor1 wall} + $w create line 408 208 475 208 -fill $color -tags {floor1 wall} + $w create line 484 278 484 311 -fill $color -tags {floor1 wall} + $w create line 484 311 508 311 -fill $color -tags {floor1 wall} + $w create line 508 327 508 311 -fill $color -tags {floor1 wall} + $w create line 559 327 508 327 -fill $color -tags {floor1 wall} + $w create line 644 391 559 391 -fill $color -tags {floor1 wall} + $w create line 644 389 644 391 -fill $color -tags {floor1 wall} + $w create line 514 205 475 205 -fill $color -tags {floor1 wall} + $w create line 496 189 496 187 -fill $color -tags {floor1 wall} + $w create line 559 129 484 129 -fill $color -tags {floor1 wall} + $w create line 484 162 484 129 -fill $color -tags {floor1 wall} + $w create line 725 133 559 133 -fill $color -tags {floor1 wall} + $w create line 559 129 559 133 -fill $color -tags {floor1 wall} + $w create line 725 149 725 167 -fill $color -tags {floor1 wall} + $w create line 725 129 802 129 -fill $color -tags {floor1 wall} + $w create line 802 389 802 129 -fill $color -tags {floor1 wall} + $w create line 739 167 802 167 -fill $color -tags {floor1 wall} + $w create line 396 188 408 188 -fill $color -tags {floor1 wall} + $w create line 0 337 9 337 -fill $color -tags {floor1 wall} + $w create line 58 337 21 337 -fill $color -tags {floor1 wall} + $w create line 43 391 43 337 -fill $color -tags {floor1 wall} + $w create line 105 337 75 337 -fill $color -tags {floor1 wall} + $w create line 91 387 91 337 -fill $color -tags {floor1 wall} + $w create line 154 337 117 337 -fill $color -tags {floor1 wall} + $w create line 139 387 139 337 -fill $color -tags {floor1 wall} + $w create line 227 337 166 337 -fill $color -tags {floor1 wall} + $w create line 258 337 251 337 -fill $color -tags {floor1 wall} + $w create line 258 328 302 328 -fill $color -tags {floor1 wall} + $w create line 302 355 302 311 -fill $color -tags {floor1 wall} + $w create line 395 311 302 311 -fill $color -tags {floor1 wall} + $w create line 484 278 395 278 -fill $color -tags {floor1 wall} + $w create line 395 294 395 278 -fill $color -tags {floor1 wall} + $w create line 473 278 473 275 -fill $color -tags {floor1 wall} + $w create line 473 256 473 254 -fill $color -tags {floor1 wall} + $w create line 533 257 531 254 -fill $color -tags {floor1 wall} + $w create line 553 276 551 274 -fill $color -tags {floor1 wall} + $w create line 698 276 553 276 -fill $color -tags {floor1 wall} + $w create line 559 391 559 327 -fill $color -tags {floor1 wall} + $w create line 802 389 644 389 -fill $color -tags {floor1 wall} + $w create line 741 314 741 389 -fill $color -tags {floor1 wall} + $w create line 698 280 698 167 -fill $color -tags {floor1 wall} + $w create line 707 280 698 280 -fill $color -tags {floor1 wall} + $w create line 802 280 731 280 -fill $color -tags {floor1 wall} + $w create line 741 280 741 302 -fill $color -tags {floor1 wall} + $w create line 698 167 727 167 -fill $color -tags {floor1 wall} + $w create line 725 137 725 129 -fill $color -tags {floor1 wall} + $w create line 514 254 514 175 -fill $color -tags {floor1 wall} + $w create line 496 175 514 175 -fill $color -tags {floor1 wall} + $w create line 502 175 502 162 -fill $color -tags {floor1 wall} + $w create line 475 166 475 162 -fill $color -tags {floor1 wall} + $w create line 496 176 496 175 -fill $color -tags {floor1 wall} + $w create line 491 189 496 189 -fill $color -tags {floor1 wall} + $w create line 491 205 491 189 -fill $color -tags {floor1 wall} + $w create line 487 238 475 238 -fill $color -tags {floor1 wall} + $w create line 487 240 487 238 -fill $color -tags {floor1 wall} + $w create line 487 252 487 254 -fill $color -tags {floor1 wall} + $w create line 315 133 304 133 -fill $color -tags {floor1 wall} + $w create line 256 133 280 133 -fill $color -tags {floor1 wall} + $w create line 78 247 270 247 -fill $color -tags {floor1 wall} + $w create line 307 247 294 247 -fill $color -tags {floor1 wall} + $w create line 214 133 232 133 -fill $color -tags {floor1 wall} + $w create line 217 247 217 266 -fill $color -tags {floor1 wall} + $w create line 217 309 217 291 -fill $color -tags {floor1 wall} + $w create line 217 309 172 309 -fill $color -tags {floor1 wall} + $w create line 154 309 148 309 -fill $color -tags {floor1 wall} + $w create line 175 300 175 309 -fill $color -tags {floor1 wall} + $w create line 151 300 175 300 -fill $color -tags {floor1 wall} + $w create line 151 247 151 309 -fill $color -tags {floor1 wall} + $w create line 78 237 78 265 -fill $color -tags {floor1 wall} + $w create line 78 286 78 309 -fill $color -tags {floor1 wall} + $w create line 106 309 78 309 -fill $color -tags {floor1 wall} + $w create line 130 309 125 309 -fill $color -tags {floor1 wall} + $w create line 99 309 99 247 -fill $color -tags {floor1 wall} + $w create line 127 299 99 299 -fill $color -tags {floor1 wall} + $w create line 127 309 127 299 -fill $color -tags {floor1 wall} + $w create line 155 191 137 191 -fill $color -tags {floor1 wall} + $w create line 137 169 137 191 -fill $color -tags {floor1 wall} + $w create line 78 171 78 169 -fill $color -tags {floor1 wall} + $w create line 78 190 78 218 -fill $color -tags {floor1 wall} + $w create line 86 192 86 169 -fill $color -tags {floor1 wall} + $w create line 86 192 78 192 -fill $color -tags {floor1 wall} + $w create line 52 301 3 301 -fill $color -tags {floor1 wall} + $w create line 52 286 52 301 -fill $color -tags {floor1 wall} + $w create line 52 252 3 252 -fill $color -tags {floor1 wall} + $w create line 52 203 3 203 -fill $color -tags {floor1 wall} + $w create line 3 156 52 156 -fill $color -tags {floor1 wall} + $w create line 8 25 8 114 -fill $color -tags {floor1 wall} + $w create line 63 114 3 114 -fill $color -tags {floor1 wall} + $w create line 75 114 97 114 -fill $color -tags {floor1 wall} + $w create line 108 114 129 114 -fill $color -tags {floor1 wall} + $w create line 129 114 129 89 -fill $color -tags {floor1 wall} + $w create line 52 114 52 128 -fill $color -tags {floor1 wall} + $w create line 132 89 88 89 -fill $color -tags {floor1 wall} + $w create line 88 25 88 89 -fill $color -tags {floor1 wall} + $w create line 88 114 88 89 -fill $color -tags {floor1 wall} + $w create line 218 89 144 89 -fill $color -tags {floor1 wall} + $w create line 147 111 147 129 -fill $color -tags {floor1 wall} + $w create line 162 111 147 111 -fill $color -tags {floor1 wall} + $w create line 162 109 162 111 -fill $color -tags {floor1 wall} + $w create line 162 96 162 89 -fill $color -tags {floor1 wall} + $w create line 218 89 218 94 -fill $color -tags {floor1 wall} + $w create line 218 89 218 119 -fill $color -tags {floor1 wall} + $w create line 8 25 88 25 -fill $color -tags {floor1 wall} + $w create line 258 337 258 328 -fill $color -tags {floor1 wall} + $w create line 113 129 96 129 -fill $color -tags {floor1 wall} + $w create line 302 355 258 355 -fill $color -tags {floor1 wall} + $w create line 386 104 386 129 -fill $color -tags {floor1 wall} + $w create line 377 100 386 104 -fill $color -tags {floor1 wall} + $w create line 365 94 377 100 -fill $color -tags {floor1 wall} + $w create line 350 83 365 94 -fill $color -tags {floor1 wall} + $w create line 337 70 350 83 -fill $color -tags {floor1 wall} + $w create line 337 70 323 56 -fill $color -tags {floor1 wall} + $w create line 312 49 323 56 -fill $color -tags {floor1 wall} + $w create line 295 40 312 49 -fill $color -tags {floor1 wall} + $w create line 282 37 295 40 -fill $color -tags {floor1 wall} + $w create line 260 34 282 37 -fill $color -tags {floor1 wall} + $w create line 253 34 260 34 -fill $color -tags {floor1 wall} + $w create line 386 128 386 104 -fill $color -tags {floor1 wall} + $w create line 113 152 156 152 -fill $color -tags {floor1 wall} + $w create line 113 152 156 152 -fill $color -tags {floor1 wall} + $w create line 113 152 113 129 -fill $color -tags {floor1 wall} + } + + # fg2 -- + # This procedure represents part of the floorplan database. When + # invoked, it instantiates the foreground information for the second + # floor (office outlines and numbers). + # + # Arguments: + # w - The canvas window. + # color - Color to use for drawing foreground information. + + proc fg2 {w color} { + global floorLabels floorItems + set i [$w create polygon 748 188 755 188 755 205 758 205 758 222 800 222 800 168 748 168 -fill {} -tags {floor2 room}] + set floorLabels($i) 238 + set {floorItems(238)} $i + $w create text 774 195 -text 238 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 726 188 746 188 746 166 800 166 800 131 726 131 -fill {} -tags {floor2 room}] + set floorLabels($i) 237 + set {floorItems(237)} $i + $w create text 763 148.5 -text 237 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 497 187 497 204 559 204 559 324 641 324 643 324 643 291 641 291 641 205 696 205 696 291 694 291 694 314 715 314 715 291 715 205 755 205 755 190 724 190 724 187 -fill {} -tags {floor2 room}] + set floorLabels($i) 246 + set {floorItems(246)} $i + $w create text 600 264 -text 246 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 694 279 643 279 643 314 694 314 -fill {} -tags {floor2 room}] + set floorLabels($i) 247 + set {floorItems(247)} $i + $w create text 668.5 296.5 -text 247 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 232 250 308 250 308 242 339 242 339 246 397 246 397 255 476 255 476 250 482 250 559 250 559 274 482 274 482 278 396 278 396 274 232 274 -fill {} -tags {floor2 room}] + set floorLabels($i) 202 + set {floorItems(202)} $i + $w create text 285.5 260 -text 202 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 53 228 53 338 176 338 233 338 233 196 306 196 306 180 175 180 175 169 156 169 156 196 176 196 176 228 -fill {} -tags {floor2 room}] + set floorLabels($i) 206 + set {floorItems(206)} $i + $w create text 143 267 -text 206 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 51 277 6 277 6 338 51 338 -fill {} -tags {floor2 room}] + set floorLabels($i) 212 + set {floorItems(212)} $i + $w create text 28.5 307.5 -text 212 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 557 276 486 276 486 309 510 309 510 325 557 325 -fill {} -tags {floor2 room}] + set floorLabels($i) 245 + set {floorItems(245)} $i + $w create text 521.5 300.5 -text 245 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 560 389 599 389 599 326 560 326 -fill {} -tags {floor2 room}] + set floorLabels($i) 244 + set {floorItems(244)} $i + $w create text 579.5 357.5 -text 244 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 601 389 601 326 643 326 643 389 -fill {} -tags {floor2 room}] + set floorLabels($i) 243 + set {floorItems(243)} $i + $w create text 622 357.5 -text 243 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 688 316 645 316 645 365 688 365 -fill {} -tags {floor2 room}] + set floorLabels($i) 242 + set {floorItems(242)} $i + $w create text 666.5 340.5 -text 242 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 802 367 759 367 759 226 802 226 -fill {} -tags {floor2 room}] + set floorLabels($i) {Barbecue Deck} + set {floorItems(Barbecue Deck)} $i + $w create text 780.5 296.5 -text {Barbecue Deck} -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 755 262 755 314 717 314 717 262 -fill {} -tags {floor2 room}] + set floorLabels($i) 240 + set {floorItems(240)} $i + $w create text 736 288 -text 240 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 755 316 689 316 689 365 755 365 -fill {} -tags {floor2 room}] + set floorLabels($i) 241 + set {floorItems(241)} $i + $w create text 722 340.5 -text 241 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 755 206 717 206 717 261 755 261 -fill {} -tags {floor2 room}] + set floorLabels($i) 239 + set {floorItems(239)} $i + $w create text 736 233.5 -text 239 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 695 277 643 277 643 206 695 206 -fill {} -tags {floor2 room}] + set floorLabels($i) 248 + set {floorItems(248)} $i + $w create text 669 241.5 -text 248 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 676 135 676 185 724 185 724 135 -fill {} -tags {floor2 room}] + set floorLabels($i) 236 + set {floorItems(236)} $i + $w create text 700 160 -text 236 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 675 135 635 135 635 145 628 145 628 185 675 185 -fill {} -tags {floor2 room}] + set floorLabels($i) 235 + set {floorItems(235)} $i + $w create text 651.5 160 -text 235 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 626 143 633 143 633 135 572 135 572 143 579 143 579 185 626 185 -fill {} -tags {floor2 room}] + set floorLabels($i) 234 + set {floorItems(234)} $i + $w create text 606 160 -text 234 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 557 135 571 135 571 145 578 145 578 185 527 185 527 131 557 131 -fill {} -tags {floor2 room}] + set floorLabels($i) 233 + set {floorItems(233)} $i + $w create text 552.5 158 -text 233 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 476 249 557 249 557 205 476 205 -fill {} -tags {floor2 room}] + set floorLabels($i) 230 + set {floorItems(230)} $i + $w create text 516.5 227 -text 230 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 476 164 486 164 486 131 525 131 525 185 476 185 -fill {} -tags {floor2 room}] + set floorLabels($i) 232 + set {floorItems(232)} $i + $w create text 500.5 158 -text 232 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 476 186 495 186 495 204 476 204 -fill {} -tags {floor2 room}] + set floorLabels($i) 229 + set {floorItems(229)} $i + $w create text 485.5 195 -text 229 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 474 207 409 207 409 187 399 187 399 164 474 164 -fill {} -tags {floor2 room}] + set floorLabels($i) 227 + set {floorItems(227)} $i + $w create text 436.5 185.5 -text 227 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 399 228 399 253 474 253 474 209 409 209 409 228 -fill {} -tags {floor2 room}] + set floorLabels($i) 228 + set {floorItems(228)} $i + $w create text 436.5 231 -text 228 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 397 246 397 226 407 226 407 189 377 189 377 246 -fill {} -tags {floor2 room}] + set floorLabels($i) 226 + set {floorItems(226)} $i + $w create text 392 217.5 -text 226 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 377 169 316 169 316 131 397 131 397 188 377 188 -fill {} -tags {floor2 room}] + set floorLabels($i) 225 + set {floorItems(225)} $i + $w create text 356.5 150 -text 225 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 234 198 306 198 306 249 234 249 -fill {} -tags {floor2 room}] + set floorLabels($i) 224 + set {floorItems(224)} $i + $w create text 270 223.5 -text 224 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 270 179 306 179 306 170 314 170 314 135 270 135 -fill {} -tags {floor2 room}] + set floorLabels($i) 223 + set {floorItems(223)} $i + $w create text 292 157 -text 223 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 268 179 221 179 221 135 268 135 -fill {} -tags {floor2 room}] + set floorLabels($i) 222 + set {floorItems(222)} $i + $w create text 244.5 157 -text 222 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 177 179 219 179 219 135 177 135 -fill {} -tags {floor2 room}] + set floorLabels($i) 221 + set {floorItems(221)} $i + $w create text 198 157 -text 221 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 299 327 349 327 349 284 341 284 341 276 299 276 -fill {} -tags {floor2 room}] + set floorLabels($i) 204 + set {floorItems(204)} $i + $w create text 324 301.5 -text 204 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 234 276 297 276 297 327 257 327 257 338 234 338 -fill {} -tags {floor2 room}] + set floorLabels($i) 205 + set {floorItems(205)} $i + $w create text 265.5 307 -text 205 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 256 385 256 340 212 340 212 385 -fill {} -tags {floor2 room}] + set floorLabels($i) 207 + set {floorItems(207)} $i + $w create text 234 362.5 -text 207 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 210 340 164 340 164 385 210 385 -fill {} -tags {floor2 room}] + set floorLabels($i) 208 + set {floorItems(208)} $i + $w create text 187 362.5 -text 208 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 115 340 162 340 162 385 115 385 -fill {} -tags {floor2 room}] + set floorLabels($i) 209 + set {floorItems(209)} $i + $w create text 138.5 362.5 -text 209 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 89 228 89 156 53 156 53 228 -fill {} -tags {floor2 room}] + set floorLabels($i) 217 + set {floorItems(217)} $i + $w create text 71 192 -text 217 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 89 169 97 169 97 190 89 190 -fill {} -tags {floor2 room}] + set floorLabels($i) 217A + set {floorItems(217A)} $i + $w create text 93 179.5 -text 217A -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 89 156 89 168 95 168 95 135 53 135 53 156 -fill {} -tags {floor2 room}] + set floorLabels($i) 216 + set {floorItems(216)} $i + $w create text 71 145.5 -text 216 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 51 179 51 135 6 135 6 179 -fill {} -tags {floor2 room}] + set floorLabels($i) 215 + set {floorItems(215)} $i + $w create text 28.5 157 -text 215 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 51 227 6 227 6 180 51 180 -fill {} -tags {floor2 room}] + set floorLabels($i) 214 + set {floorItems(214)} $i + $w create text 28.5 203.5 -text 214 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 51 275 6 275 6 229 51 229 -fill {} -tags {floor2 room}] + set floorLabels($i) 213 + set {floorItems(213)} $i + $w create text 28.5 252 -text 213 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 114 340 67 340 67 385 114 385 -fill {} -tags {floor2 room}] + set floorLabels($i) 210 + set {floorItems(210)} $i + $w create text 90.5 362.5 -text 210 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 59 389 59 385 65 385 65 340 1 340 1 389 -fill {} -tags {floor2 room}] + set floorLabels($i) 211 + set {floorItems(211)} $i + $w create text 33 364.5 -text 211 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 393 309 350 309 350 282 342 282 342 276 393 276 -fill {} -tags {floor2 room}] + set floorLabels($i) 203 + set {floorItems(203)} $i + $w create text 367.5 292.5 -text 203 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 99 191 91 191 91 226 174 226 174 198 154 198 154 192 109 192 109 169 99 169 -fill {} -tags {floor2 room}] + set floorLabels($i) 220 + set {floorItems(220)} $i + $w create text 132.5 208.5 -text 220 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -tags {floor2 room}] + set floorLabels($i) {Priv Lift2} + set {floorItems(Priv Lift2)} $i + $w create text 323 188 -text {Priv Lift2} -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -tags {floor2 room}] + set floorLabels($i) {Pub Lift 2} + set {floorItems(Pub Lift 2)} $i + $w create text 323 223 -text {Pub Lift 2} -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -tags {floor2 room}] + set floorLabels($i) 218 + set {floorItems(218)} $i + $w create text 136 149.5 -text 218 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -tags {floor2 room}] + set floorLabels($i) 219 + set {floorItems(219)} $i + $w create text 132.5 180 -text 219 -fill $color -anchor c -tags {floor2 label} + set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -tags {floor2 room}] + set floorLabels($i) 201 + set {floorItems(201)} $i + $w create text 358 209 -text 201 -fill $color -anchor c -tags {floor2 label} + $w create line 641 186 678 186 -fill $color -tags {floor2 wall} + $w create line 757 350 757 367 -fill $color -tags {floor2 wall} + $w create line 634 133 634 144 -fill $color -tags {floor2 wall} + $w create line 634 144 627 144 -fill $color -tags {floor2 wall} + $w create line 572 133 572 144 -fill $color -tags {floor2 wall} + $w create line 572 144 579 144 -fill $color -tags {floor2 wall} + $w create line 398 129 398 162 -fill $color -tags {floor2 wall} + $w create line 174 197 175 197 -fill $color -tags {floor2 wall} + $w create line 175 197 175 227 -fill $color -tags {floor2 wall} + $w create line 757 206 757 221 -fill $color -tags {floor2 wall} + $w create line 396 188 408 188 -fill $color -tags {floor2 wall} + $w create line 727 189 725 189 -fill $color -tags {floor2 wall} + $w create line 747 167 802 167 -fill $color -tags {floor2 wall} + $w create line 747 167 747 189 -fill $color -tags {floor2 wall} + $w create line 755 189 739 189 -fill $color -tags {floor2 wall} + $w create line 769 224 757 224 -fill $color -tags {floor2 wall} + $w create line 802 224 802 129 -fill $color -tags {floor2 wall} + $w create line 802 129 725 129 -fill $color -tags {floor2 wall} + $w create line 725 189 725 129 -fill $color -tags {floor2 wall} + $w create line 725 186 690 186 -fill $color -tags {floor2 wall} + $w create line 676 133 676 186 -fill $color -tags {floor2 wall} + $w create line 627 144 627 186 -fill $color -tags {floor2 wall} + $w create line 629 186 593 186 -fill $color -tags {floor2 wall} + $w create line 579 144 579 186 -fill $color -tags {floor2 wall} + $w create line 559 129 559 133 -fill $color -tags {floor2 wall} + $w create line 725 133 559 133 -fill $color -tags {floor2 wall} + $w create line 484 162 484 129 -fill $color -tags {floor2 wall} + $w create line 559 129 484 129 -fill $color -tags {floor2 wall} + $w create line 526 129 526 186 -fill $color -tags {floor2 wall} + $w create line 540 186 581 186 -fill $color -tags {floor2 wall} + $w create line 528 186 523 186 -fill $color -tags {floor2 wall} + $w create line 511 186 475 186 -fill $color -tags {floor2 wall} + $w create line 496 190 496 186 -fill $color -tags {floor2 wall} + $w create line 496 205 496 202 -fill $color -tags {floor2 wall} + $w create line 475 205 527 205 -fill $color -tags {floor2 wall} + $w create line 558 205 539 205 -fill $color -tags {floor2 wall} + $w create line 558 205 558 249 -fill $color -tags {floor2 wall} + $w create line 558 249 475 249 -fill $color -tags {floor2 wall} + $w create line 662 206 642 206 -fill $color -tags {floor2 wall} + $w create line 695 206 675 206 -fill $color -tags {floor2 wall} + $w create line 695 278 642 278 -fill $color -tags {floor2 wall} + $w create line 642 291 642 206 -fill $color -tags {floor2 wall} + $w create line 695 291 695 206 -fill $color -tags {floor2 wall} + $w create line 716 208 716 206 -fill $color -tags {floor2 wall} + $w create line 757 206 716 206 -fill $color -tags {floor2 wall} + $w create line 757 221 757 224 -fill $color -tags {floor2 wall} + $w create line 793 224 802 224 -fill $color -tags {floor2 wall} + $w create line 757 262 716 262 -fill $color -tags {floor2 wall} + $w create line 716 220 716 264 -fill $color -tags {floor2 wall} + $w create line 716 315 716 276 -fill $color -tags {floor2 wall} + $w create line 757 315 703 315 -fill $color -tags {floor2 wall} + $w create line 757 325 757 224 -fill $color -tags {floor2 wall} + $w create line 757 367 644 367 -fill $color -tags {floor2 wall} + $w create line 689 367 689 315 -fill $color -tags {floor2 wall} + $w create line 647 315 644 315 -fill $color -tags {floor2 wall} + $w create line 659 315 691 315 -fill $color -tags {floor2 wall} + $w create line 600 325 600 391 -fill $color -tags {floor2 wall} + $w create line 627 325 644 325 -fill $color -tags {floor2 wall} + $w create line 644 391 644 315 -fill $color -tags {floor2 wall} + $w create line 615 325 575 325 -fill $color -tags {floor2 wall} + $w create line 644 391 558 391 -fill $color -tags {floor2 wall} + $w create line 563 325 558 325 -fill $color -tags {floor2 wall} + $w create line 558 391 558 314 -fill $color -tags {floor2 wall} + $w create line 558 327 508 327 -fill $color -tags {floor2 wall} + $w create line 558 275 484 275 -fill $color -tags {floor2 wall} + $w create line 558 302 558 275 -fill $color -tags {floor2 wall} + $w create line 508 327 508 311 -fill $color -tags {floor2 wall} + $w create line 484 311 508 311 -fill $color -tags {floor2 wall} + $w create line 484 275 484 311 -fill $color -tags {floor2 wall} + $w create line 475 208 408 208 -fill $color -tags {floor2 wall} + $w create line 408 206 408 210 -fill $color -tags {floor2 wall} + $w create line 408 222 408 227 -fill $color -tags {floor2 wall} + $w create line 408 227 398 227 -fill $color -tags {floor2 wall} + $w create line 398 227 398 254 -fill $color -tags {floor2 wall} + $w create line 408 188 408 194 -fill $color -tags {floor2 wall} + $w create line 383 188 376 188 -fill $color -tags {floor2 wall} + $w create line 398 188 398 162 -fill $color -tags {floor2 wall} + $w create line 398 162 484 162 -fill $color -tags {floor2 wall} + $w create line 475 162 475 254 -fill $color -tags {floor2 wall} + $w create line 398 254 475 254 -fill $color -tags {floor2 wall} + $w create line 484 280 395 280 -fill $color -tags {floor2 wall} + $w create line 395 311 395 275 -fill $color -tags {floor2 wall} + $w create line 307 197 293 197 -fill $color -tags {floor2 wall} + $w create line 278 197 233 197 -fill $color -tags {floor2 wall} + $w create line 233 197 233 249 -fill $color -tags {floor2 wall} + $w create line 307 179 284 179 -fill $color -tags {floor2 wall} + $w create line 233 249 278 249 -fill $color -tags {floor2 wall} + $w create line 269 179 269 133 -fill $color -tags {floor2 wall} + $w create line 220 179 220 133 -fill $color -tags {floor2 wall} + $w create line 155 191 110 191 -fill $color -tags {floor2 wall} + $w create line 90 190 98 190 -fill $color -tags {floor2 wall} + $w create line 98 169 98 190 -fill $color -tags {floor2 wall} + $w create line 52 133 52 165 -fill $color -tags {floor2 wall} + $w create line 52 214 52 177 -fill $color -tags {floor2 wall} + $w create line 52 226 52 262 -fill $color -tags {floor2 wall} + $w create line 52 274 52 276 -fill $color -tags {floor2 wall} + $w create line 234 275 234 339 -fill $color -tags {floor2 wall} + $w create line 226 339 258 339 -fill $color -tags {floor2 wall} + $w create line 211 387 211 339 -fill $color -tags {floor2 wall} + $w create line 214 339 177 339 -fill $color -tags {floor2 wall} + $w create line 258 387 60 387 -fill $color -tags {floor2 wall} + $w create line 3 133 3 339 -fill $color -tags {floor2 wall} + $w create line 165 339 129 339 -fill $color -tags {floor2 wall} + $w create line 117 339 80 339 -fill $color -tags {floor2 wall} + $w create line 68 339 59 339 -fill $color -tags {floor2 wall} + $w create line 0 339 46 339 -fill $color -tags {floor2 wall} + $w create line 60 391 0 391 -fill $color -tags {floor2 wall} + $w create line 0 339 0 391 -fill $color -tags {floor2 wall} + $w create line 60 387 60 391 -fill $color -tags {floor2 wall} + $w create line 258 329 258 387 -fill $color -tags {floor2 wall} + $w create line 350 329 258 329 -fill $color -tags {floor2 wall} + $w create line 395 311 350 311 -fill $color -tags {floor2 wall} + $w create line 398 129 315 129 -fill $color -tags {floor2 wall} + $w create line 176 133 315 133 -fill $color -tags {floor2 wall} + $w create line 176 129 96 129 -fill $color -tags {floor2 wall} + $w create line 3 133 96 133 -fill $color -tags {floor2 wall} + $w create line 66 387 66 339 -fill $color -tags {floor2 wall} + $w create line 115 387 115 339 -fill $color -tags {floor2 wall} + $w create line 163 387 163 339 -fill $color -tags {floor2 wall} + $w create line 234 275 276 275 -fill $color -tags {floor2 wall} + $w create line 288 275 309 275 -fill $color -tags {floor2 wall} + $w create line 298 275 298 329 -fill $color -tags {floor2 wall} + $w create line 341 283 350 283 -fill $color -tags {floor2 wall} + $w create line 321 275 341 275 -fill $color -tags {floor2 wall} + $w create line 375 275 395 275 -fill $color -tags {floor2 wall} + $w create line 315 129 315 170 -fill $color -tags {floor2 wall} + $w create line 376 170 307 170 -fill $color -tags {floor2 wall} + $w create line 307 250 307 170 -fill $color -tags {floor2 wall} + $w create line 376 245 376 170 -fill $color -tags {floor2 wall} + $w create line 340 241 307 241 -fill $color -tags {floor2 wall} + $w create line 340 245 340 224 -fill $color -tags {floor2 wall} + $w create line 340 210 340 201 -fill $color -tags {floor2 wall} + $w create line 340 187 340 170 -fill $color -tags {floor2 wall} + $w create line 340 206 307 206 -fill $color -tags {floor2 wall} + $w create line 293 250 307 250 -fill $color -tags {floor2 wall} + $w create line 271 179 238 179 -fill $color -tags {floor2 wall} + $w create line 226 179 195 179 -fill $color -tags {floor2 wall} + $w create line 176 129 176 179 -fill $color -tags {floor2 wall} + $w create line 182 179 176 179 -fill $color -tags {floor2 wall} + $w create line 174 169 176 169 -fill $color -tags {floor2 wall} + $w create line 162 169 90 169 -fill $color -tags {floor2 wall} + $w create line 96 169 96 129 -fill $color -tags {floor2 wall} + $w create line 175 227 90 227 -fill $color -tags {floor2 wall} + $w create line 90 190 90 227 -fill $color -tags {floor2 wall} + $w create line 52 179 3 179 -fill $color -tags {floor2 wall} + $w create line 52 228 3 228 -fill $color -tags {floor2 wall} + $w create line 52 276 3 276 -fill $color -tags {floor2 wall} + $w create line 155 177 155 169 -fill $color -tags {floor2 wall} + $w create line 110 191 110 169 -fill $color -tags {floor2 wall} + $w create line 155 189 155 197 -fill $color -tags {floor2 wall} + $w create line 350 283 350 329 -fill $color -tags {floor2 wall} + $w create line 162 197 155 197 -fill $color -tags {floor2 wall} + $w create line 341 275 341 283 -fill $color -tags {floor2 wall} + } + + # fg3 -- + # This procedure represents part of the floorplan database. When + # invoked, it instantiates the foreground information for the third + # floor (office outlines and numbers). + # + # Arguments: + # w - The canvas window. + # color - Color to use for drawing foreground information. + + proc fg3 {w color} { + global floorLabels floorItems + set i [$w create polygon 89 228 89 180 70 180 70 228 -fill {} -tags {floor3 room}] + set floorLabels($i) 316 + set {floorItems(316)} $i + $w create text 79.5 204 -text 316 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 115 368 162 368 162 323 115 323 -fill {} -tags {floor3 room}] + set floorLabels($i) 309 + set {floorItems(309)} $i + $w create text 138.5 345.5 -text 309 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 164 323 164 368 211 368 211 323 -fill {} -tags {floor3 room}] + set floorLabels($i) 308 + set {floorItems(308)} $i + $w create text 187.5 345.5 -text 308 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 256 368 212 368 212 323 256 323 -fill {} -tags {floor3 room}] + set floorLabels($i) 307 + set {floorItems(307)} $i + $w create text 234 345.5 -text 307 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 244 276 297 276 297 327 260 327 260 321 244 321 -fill {} -tags {floor3 room}] + set floorLabels($i) 305 + set {floorItems(305)} $i + $w create text 270.5 301.5 -text 305 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 251 219 251 203 244 203 244 219 -fill {} -tags {floor3 room}] + set floorLabels($i) 324B + set {floorItems(324B)} $i + $w create text 247.5 211 -text 324B -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 251 249 244 249 244 232 251 232 -fill {} -tags {floor3 room}] + set floorLabels($i) 324A + set {floorItems(324A)} $i + $w create text 247.5 240.5 -text 324A -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 223 135 223 179 177 179 177 135 -fill {} -tags {floor3 room}] + set floorLabels($i) 320 + set {floorItems(320)} $i + $w create text 200 157 -text 320 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 114 368 114 323 67 323 67 368 -fill {} -tags {floor3 room}] + set floorLabels($i) 310 + set {floorItems(310)} $i + $w create text 90.5 345.5 -text 310 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 23 277 23 321 68 321 68 277 -fill {} -tags {floor3 room}] + set floorLabels($i) 312 + set {floorItems(312)} $i + $w create text 45.5 299 -text 312 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 23 229 68 229 68 275 23 275 -fill {} -tags {floor3 room}] + set floorLabels($i) 313 + set {floorItems(313)} $i + $w create text 45.5 252 -text 313 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 68 227 23 227 23 180 68 180 -fill {} -tags {floor3 room}] + set floorLabels($i) 314 + set {floorItems(314)} $i + $w create text 45.5 203.5 -text 314 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 95 179 95 135 23 135 23 179 -fill {} -tags {floor3 room}] + set floorLabels($i) 315 + set {floorItems(315)} $i + $w create text 59 157 -text 315 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 99 226 99 204 91 204 91 226 -fill {} -tags {floor3 room}] + set floorLabels($i) 316B + set {floorItems(316B)} $i + $w create text 95 215 -text 316B -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 91 202 99 202 99 180 91 180 -fill {} -tags {floor3 room}] + set floorLabels($i) 316A + set {floorItems(316A)} $i + $w create text 95 191 -text 316A -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 97 169 109 169 109 192 154 192 154 198 174 198 174 226 101 226 101 179 97 179 -fill {} -tags {floor3 room}] + set floorLabels($i) 319 + set {floorItems(319)} $i + $w create text 141.5 209 -text 319 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 65 368 58 368 58 389 1 389 1 333 23 333 23 323 65 323 -fill {} -tags {floor3 room}] + set floorLabels($i) 311 + set {floorItems(311)} $i + $w create text 29.5 361 -text 311 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 154 191 111 191 111 169 154 169 -fill {} -tags {floor3 room}] + set floorLabels($i) 318 + set {floorItems(318)} $i + $w create text 132.5 180 -text 318 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 175 168 97 168 97 131 175 131 -fill {} -tags {floor3 room}] + set floorLabels($i) 317 + set {floorItems(317)} $i + $w create text 136 149.5 -text 317 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 274 194 274 221 306 221 306 194 -fill {} -tags {floor3 room}] + set floorLabels($i) 323 + set {floorItems(323)} $i + $w create text 290 207.5 -text 323 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 306 222 274 222 274 249 306 249 -fill {} -tags {floor3 room}] + set floorLabels($i) 325 + set {floorItems(325)} $i + $w create text 290 235.5 -text 325 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 263 179 224 179 224 135 263 135 -fill {} -tags {floor3 room}] + set floorLabels($i) 321 + set {floorItems(321)} $i + $w create text 243.5 157 -text 321 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 314 169 306 169 306 192 273 192 264 181 264 135 314 135 -fill {} -tags {floor3 room}] + set floorLabels($i) 322 + set {floorItems(322)} $i + $w create text 293.5 163.5 -text 322 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 307 240 339 240 339 206 307 206 -fill {} -tags {floor3 room}] + set floorLabels($i) {Pub Lift3} + set {floorItems(Pub Lift3)} $i + $w create text 323 223 -text {Pub Lift3} -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 339 205 307 205 307 171 339 171 -fill {} -tags {floor3 room}] + set floorLabels($i) {Priv Lift3} + set {floorItems(Priv Lift3)} $i + $w create text 323 188 -text {Priv Lift3} -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 350 284 376 284 376 276 397 276 397 309 350 309 -fill {} -tags {floor3 room}] + set floorLabels($i) 303 + set {floorItems(303)} $i + $w create text 373.5 292.5 -text 303 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 272 203 272 249 252 249 252 230 244 230 244 221 252 221 252 203 -fill {} -tags {floor3 room}] + set floorLabels($i) 324 + set {floorItems(324)} $i + $w create text 262 226 -text 324 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 299 276 299 327 349 327 349 284 341 284 341 276 -fill {} -tags {floor3 room}] + set floorLabels($i) 304 + set {floorItems(304)} $i + $w create text 324 301.5 -text 304 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 375 246 375 172 341 172 341 246 -fill {} -tags {floor3 room}] + set floorLabels($i) 301 + set {floorItems(301)} $i + $w create text 358 209 -text 301 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 397 246 377 246 377 185 397 185 -fill {} -tags {floor3 room}] + set floorLabels($i) 327 + set {floorItems(327)} $i + $w create text 387 215.5 -text 327 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 316 131 316 169 377 169 377 185 397 185 397 131 -fill {} -tags {floor3 room}] + set floorLabels($i) 326 + set {floorItems(326)} $i + $w create text 356.5 150 -text 326 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 308 251 242 251 242 274 342 274 342 282 375 282 375 274 397 274 397 248 339 248 339 242 308 242 -fill {} -tags {floor3 room}] + set floorLabels($i) 302 + set {floorItems(302)} $i + $w create text 319.5 261 -text 302 -fill $color -anchor c -tags {floor3 label} + set i [$w create polygon 70 321 242 321 242 200 259 200 259 203 272 203 272 193 263 180 242 180 175 180 175 169 156 169 156 196 177 196 177 228 107 228 70 228 70 275 107 275 107 248 160 248 160 301 107 301 107 275 70 275 -fill {} -tags {floor3 room}] + set floorLabels($i) 306 + set {floorItems(306)} $i + $w create text 200.5 284.5 -text 306 -fill $color -anchor c -tags {floor3 label} + $w create line 341 275 341 283 -fill $color -tags {floor3 wall} + $w create line 162 197 155 197 -fill $color -tags {floor3 wall} + $w create line 396 247 399 247 -fill $color -tags {floor3 wall} + $w create line 399 129 399 311 -fill $color -tags {floor3 wall} + $w create line 258 202 243 202 -fill $color -tags {floor3 wall} + $w create line 350 283 350 329 -fill $color -tags {floor3 wall} + $w create line 251 231 243 231 -fill $color -tags {floor3 wall} + $w create line 243 220 251 220 -fill $color -tags {floor3 wall} + $w create line 243 250 243 202 -fill $color -tags {floor3 wall} + $w create line 155 197 155 190 -fill $color -tags {floor3 wall} + $w create line 110 192 110 169 -fill $color -tags {floor3 wall} + $w create line 155 192 110 192 -fill $color -tags {floor3 wall} + $w create line 155 177 155 169 -fill $color -tags {floor3 wall} + $w create line 176 197 176 227 -fill $color -tags {floor3 wall} + $w create line 69 280 69 274 -fill $color -tags {floor3 wall} + $w create line 21 276 69 276 -fill $color -tags {floor3 wall} + $w create line 69 262 69 226 -fill $color -tags {floor3 wall} + $w create line 21 228 69 228 -fill $color -tags {floor3 wall} + $w create line 21 179 75 179 -fill $color -tags {floor3 wall} + $w create line 69 179 69 214 -fill $color -tags {floor3 wall} + $w create line 90 220 90 227 -fill $color -tags {floor3 wall} + $w create line 90 204 90 202 -fill $color -tags {floor3 wall} + $w create line 90 203 100 203 -fill $color -tags {floor3 wall} + $w create line 90 187 90 179 -fill $color -tags {floor3 wall} + $w create line 90 227 176 227 -fill $color -tags {floor3 wall} + $w create line 100 179 100 227 -fill $color -tags {floor3 wall} + $w create line 100 179 87 179 -fill $color -tags {floor3 wall} + $w create line 96 179 96 129 -fill $color -tags {floor3 wall} + $w create line 162 169 96 169 -fill $color -tags {floor3 wall} + $w create line 173 169 176 169 -fill $color -tags {floor3 wall} + $w create line 182 179 176 179 -fill $color -tags {floor3 wall} + $w create line 176 129 176 179 -fill $color -tags {floor3 wall} + $w create line 195 179 226 179 -fill $color -tags {floor3 wall} + $w create line 224 133 224 179 -fill $color -tags {floor3 wall} + $w create line 264 179 264 133 -fill $color -tags {floor3 wall} + $w create line 238 179 264 179 -fill $color -tags {floor3 wall} + $w create line 273 207 273 193 -fill $color -tags {floor3 wall} + $w create line 273 235 273 250 -fill $color -tags {floor3 wall} + $w create line 273 224 273 219 -fill $color -tags {floor3 wall} + $w create line 273 193 307 193 -fill $color -tags {floor3 wall} + $w create line 273 222 307 222 -fill $color -tags {floor3 wall} + $w create line 273 250 307 250 -fill $color -tags {floor3 wall} + $w create line 384 247 376 247 -fill $color -tags {floor3 wall} + $w create line 340 206 307 206 -fill $color -tags {floor3 wall} + $w create line 340 187 340 170 -fill $color -tags {floor3 wall} + $w create line 340 210 340 201 -fill $color -tags {floor3 wall} + $w create line 340 247 340 224 -fill $color -tags {floor3 wall} + $w create line 340 241 307 241 -fill $color -tags {floor3 wall} + $w create line 376 247 376 170 -fill $color -tags {floor3 wall} + $w create line 307 250 307 170 -fill $color -tags {floor3 wall} + $w create line 376 170 307 170 -fill $color -tags {floor3 wall} + $w create line 315 129 315 170 -fill $color -tags {floor3 wall} + $w create line 376 283 366 283 -fill $color -tags {floor3 wall} + $w create line 376 283 376 275 -fill $color -tags {floor3 wall} + $w create line 399 275 376 275 -fill $color -tags {floor3 wall} + $w create line 341 275 320 275 -fill $color -tags {floor3 wall} + $w create line 341 283 350 283 -fill $color -tags {floor3 wall} + $w create line 298 275 298 329 -fill $color -tags {floor3 wall} + $w create line 308 275 298 275 -fill $color -tags {floor3 wall} + $w create line 243 322 243 275 -fill $color -tags {floor3 wall} + $w create line 243 275 284 275 -fill $color -tags {floor3 wall} + $w create line 258 322 226 322 -fill $color -tags {floor3 wall} + $w create line 212 370 212 322 -fill $color -tags {floor3 wall} + $w create line 214 322 177 322 -fill $color -tags {floor3 wall} + $w create line 163 370 163 322 -fill $color -tags {floor3 wall} + $w create line 165 322 129 322 -fill $color -tags {floor3 wall} + $w create line 84 322 117 322 -fill $color -tags {floor3 wall} + $w create line 71 322 64 322 -fill $color -tags {floor3 wall} + $w create line 115 322 115 370 -fill $color -tags {floor3 wall} + $w create line 66 322 66 370 -fill $color -tags {floor3 wall} + $w create line 52 322 21 322 -fill $color -tags {floor3 wall} + $w create line 21 331 0 331 -fill $color -tags {floor3 wall} + $w create line 21 331 21 133 -fill $color -tags {floor3 wall} + $w create line 96 133 21 133 -fill $color -tags {floor3 wall} + $w create line 176 129 96 129 -fill $color -tags {floor3 wall} + $w create line 315 133 176 133 -fill $color -tags {floor3 wall} + $w create line 315 129 399 129 -fill $color -tags {floor3 wall} + $w create line 399 311 350 311 -fill $color -tags {floor3 wall} + $w create line 350 329 258 329 -fill $color -tags {floor3 wall} + $w create line 258 322 258 370 -fill $color -tags {floor3 wall} + $w create line 60 370 258 370 -fill $color -tags {floor3 wall} + $w create line 60 370 60 391 -fill $color -tags {floor3 wall} + $w create line 0 391 0 331 -fill $color -tags {floor3 wall} + $w create line 60 391 0 391 -fill $color -tags {floor3 wall} + $w create line 307 250 307 242 -fill $color -tags {floor3 wall} + $w create line 273 250 307 250 -fill $color -tags {floor3 wall} + $w create line 258 250 243 250 -fill $color -tags {floor3 wall} + } + + # Below is the "main program" that creates the floorplan demonstration. + + set w .floor + global c tk_library currentRoom colors activeFloor + catch {destroy $w} + toplevel $w + wm title $w "Floorplan Canvas Demonstration" + wm iconname $w "Floorplan" + wm geometry $w +20+20 + wm minsize $w 100 100 + + label $w.msg -font $font -wraplength 8i -justify left -text [langSel \ + "This window contains a canvas widget showing the floorplan of Digital Equipment Corporation's Western Research Laboratory. It has three levels. At any given time one of the levels is active, meaning that you can see its room structure. To activate a level, click the left mouse button anywhere on it. As the mouse moves over the active level, the room under the mouse lights up and its room number appears in the \"Room:\" entry. You can also type a room number in the entry and the room will light up." \ + "$B$3$N%&%#%s%I%&$K$O%G%#%8%?%k%(%/%$%C%W%a%s%Ho$K$=$N$&$A$N(B1$B3,J,$,A*Br!"$D$^$j$=$N4Ve$G%^%&%9$N:8%\%?%s$r%/%j%C%/$7$F$/$@$5$$!#%^%&%9$,A*Br$5$l$F$$$k3,$N>e$rF0$/$H!"$=$N2<$K$"$kIt20$N?'$,JQ$o$j!"It20HV9f$,!VIt20HV9f(B:$B!W%(%s%H%j$KI=<($5$l$^$9!#$^$?!"%(%s%H%j$KIt20HV9f$r=q$/$H$=$NIt20$N?'$,JQ$o$j$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + set f [frame $w.frame] + pack $f -side top -fill both -expand yes + set h [scrollbar $f.hscroll -highlightthickness 0 -orient horizontal] + set v [scrollbar $f.vscroll -highlightthickness 0 -orient vertical] + set f1 [frame $f.f1 -bd 2 -relief sunken] + set c [canvas $f1.c -width 900 -height 500 -borderwidth 0 \ + -highlightthickness 0 -xscrollcommand "$h set" -yscrollcommand "$v set"] + pack $c -expand yes -fill both + grid $f1 -padx 1 -pady 1 \ + -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid $v -padx 1 -pady 1 \ + -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news + grid $h -padx 1 -pady 1 \ + -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid rowconfig $f 0 -weight 1 -minsize 0 + grid columnconfig $f 0 -weight 1 -minsize 0 + pack $f -expand yes -fill both -padx 1 -pady 1 + + $v config -command "$c yview" + $h config -command "$c xview" + + # Create an entry for displaying and typing in current room. + + entry $c.entry -width 10 -relief sunken -bd 2 -textvariable currentRoom + + # Choose colors, then fill in the floorplan. + + if {[winfo depth $c] > 1} { + set colors(bg1) #a9c1da + set colors(outline1) #77889a + set colors(bg2) #9ab0c6 + set colors(outline2) #687786 + set colors(bg3) #8ba0b3 + set colors(outline3) #596673 + set colors(offices) Black + set colors(active) #c4d1df + } else { + set colors(bg1) white + set colors(outline1) black + set colors(bg2) white + set colors(outline2) black + set colors(bg3) white + set colors(outline3) black + set colors(offices) Black + set colors(active) black + } + set activeFloor "" + floorDisplay $c 3 + + # Set up event bindings for canvas: + + $c bind floor1 <1> "floorDisplay $c 1" + $c bind floor2 <1> "floorDisplay $c 2" + $c bind floor3 <1> "floorDisplay $c 3" + $c bind room "newRoom $c" + $c bind room {set currentRoom ""} + bind $c <2> "$c scan mark %x %y" + bind $c "$c scan dragto %x %y" + bind $c "unset currentRoom" + set currentRoom "" + trace variable currentRoom w "roomChanged $c" diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/form.tcl ./library/demos.jp/form.tcl *** ../../tk8.0.5/library/demos.jp/form.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/form.tcl Thu Apr 1 00:08:31 1999 *************** *** 0 **** --- 1,42 ---- + # form.tcl -- + # + # This demonstration script creates a simple form with a bunch + # of entry widgets. + # + # RCS: @(#) $Id: form.tcl,v 1.1 1999/03/31 15:08:31 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .form + catch {destroy $w} + toplevel $w + wm title $w "Form Demonstration" + wm iconname $w "form" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "This window contains a simple form where you can type in the various entries and use tabs to move circularly between the entries." \ + "$B$3$N%&%#%s%I%&$O4JC1$J%U%)!<%`F~NOMQ$K$J$C$F$$$F!"$5$^$6$^$J%(%s%H%j$KF~NO$,$G$-$^$9!#%?%V$G%(%s%H%j$N@ZBX$($,$G$-$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + foreach i {f1 f2 f3 f4 f5} { + frame $w.$i -bd 2 + entry $w.$i.entry -relief sunken -width 40 + label $w.$i.label + pack $w.$i.entry -side right + pack $w.$i.label -side left + } + $w.f1.label config -text [langSel Name: $BL>A0(B:] + $w.f2.label config -text [langSel Address: $B=;=j(B:] + $w.f5.label config -text [langSel Phone: $BEEOC(B:] + pack $w.msg $w.f1 $w.f2 $w.f3 $w.f4 $w.f5 -side top -fill x + bind $w "destroy $w" + focus $w.f1.entry diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/hello ./library/demos.jp/hello *** ../../tk8.0.5/library/demos.jp/hello Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/hello Thu Apr 1 00:08:32 1999 *************** *** 0 **** --- 1,18 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # hello -- + # Simple Tk script to create a button that prints "Hello, world". + # Click on the button to terminate the program. + # + # RCS: @(#) $Id: hello,v 1.1 1999/03/31 15:08:32 m-hirano Exp $ + # + # The first line below creates the button, and the second line + # asks the packer to shrink-wrap the application's main window + # around the button. + + button .hello -text "Hello, world" -command { + puts stdout "Hello, world"; destroy . + } + pack .hello diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/hscale.tcl ./library/demos.jp/hscale.tcl *** ../../tk8.0.5/library/demos.jp/hscale.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/hscale.tcl Thu Apr 1 00:08:32 1999 *************** *** 0 **** --- 1,49 ---- + # hscale.tcl -- + # + # This demonstration script shows an example with a horizontal scale. + # + # RCS: @(#) $Id: hscale.tcl,v 1.1 1999/03/31 15:08:32 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .hscale + catch {destroy $w} + toplevel $w + wm title $w "Horizontal Scale Demonstration" + wm iconname $w "hscale" + positionWindow $w + + label $w.msg -font $font -wraplength 3.5i -justify left -text [langSel \ + "An arrow and a horizontal scale are displayed below. If you click or drag mouse button 1 in the scale, you can change the length of the arrow." \ + "$B2<$K$O%P!<$H2#7?$N%9%1!<%k$,I=<($5$l$F$$$^$9!#%9%1!<%k$G%^%&%9$N%\%?%s(B1 $B$r%/%j%C%/$9$k$+%I%i%C%0$7$F%P!<$NI}$rJQ$($k$3$H$,$G$-$^$9!#=*$C$?$i!VN;2r!W%\%?%s$r2!$7$F$/$@$5$$!#(B"] + pack $w.msg -side top -padx .5c + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame -borderwidth 10 + pack $w.frame -side top -fill x + + canvas $w.frame.canvas -width 50 -height 50 -bd 0 -highlightthickness 0 + $w.frame.canvas create polygon 0 0 1 1 2 2 -fill DeepSkyBlue3 -tags poly + $w.frame.canvas create line 0 0 1 1 2 2 0 0 -fill black -tags line + scale $w.frame.scale -orient horizontal -length 284 -from 0 -to 250 \ + -command "setWidth $w.frame.canvas" -tickinterval 50 + pack $w.frame.canvas -side top -expand yes -anchor s -fill x -padx 15 + pack $w.frame.scale -side bottom -expand yes -anchor n + $w.frame.scale set 75 + + proc setWidth {w width} { + incr width 21 + set x2 [expr $width - 30] + if {$x2 < 21} { + set x2 21 + } + $w coords poly 20 15 20 35 $x2 35 $x2 45 $width 25 $x2 5 $x2 15 20 15 + $w coords line 20 15 20 35 $x2 35 $x2 45 $width 25 $x2 5 $x2 15 20 15 + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/icon.tcl ./library/demos.jp/icon.tcl *** ../../tk8.0.5/library/demos.jp/icon.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/icon.tcl Thu Apr 1 00:08:32 1999 *************** *** 0 **** --- 1,54 ---- + # icon.tcl -- + # + # This demonstration script creates a toplevel window containing + # buttons that display bitmaps instead of text. + # + # RCS: @(#) $Id: icon.tcl,v 1.1 1999/03/31 15:08:32 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .icon + catch {destroy $w} + toplevel $w + wm title $w "Iconic Button Demonstration" + wm iconname $w "icon" + positionWindow $w + + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "This window shows three ways of using bitmaps or images in radiobuttons and checkbuttons. On the left are two radiobuttons, each of which displays a bitmap and an indicator. In the middle is a checkbutton that displays a different image depending on whether it is selected or not. On the right is a checkbutton that displays a single bitmap but changes its background color to indicate whether or not it is selected." \ + "$B$3$N%&%#%s%I%&$K$O%i%8%*%\%?%s$H%A%'%C%/%\%?%s>e$K%S%C%H%^%C%W$d2hA|$rI=<($9$k(B 3 $B$D$NJ}K!$r<($7$F$$$^$9!#:8$K$"$k$N$O(B2$B$D$N%i%8%*%\%?%s$G!"$=$l$>$l$,!"%S%C%H%^%C%W$HA*Br$r<($9%$%s%8%1!<%?$G$G$-$F$$$^$9!#Cf1{$K$"$k$N$O!"A*Br:Q$_$+$I$&$+$K$h$C$F0[$J$k2hA|$rI=<($9$k%A%'%C%/%\%?%s$G$9!#1&B&$K$"$k$N$OA*Br:Q$_$+$I$&$+$K$h$C$FGX7J?'$,JQ$o$k%S%C%H%^%C%W$rI=<($9$k%A%'%C%/%\%?%s$G$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + image create bitmap flagup \ + -file [file join $tk_library demos.jp images flagup.bmp] \ + -maskfile [file join $tk_library demos.jp images flagup.bmp] + image create bitmap flagdown \ + -file [file join $tk_library demos.jp images flagdown.bmp] \ + -maskfile [file join $tk_library demos.jp images flagdown.bmp] + frame $w.frame -borderwidth 10 + pack $w.frame -side top + + checkbutton $w.frame.b1 -image flagdown -selectimage flagup \ + -indicatoron 0 + $w.frame.b1 configure -selectcolor [$w.frame.b1 cget -background] + checkbutton $w.frame.b2 \ + -bitmap @[file join $tk_library demos.jp images letters.bmp] \ + -indicatoron 0 -selectcolor SeaGreen1 + frame $w.frame.left + pack $w.frame.left $w.frame.b1 $w.frame.b2 -side left -expand yes -padx 5m + + radiobutton $w.frame.left.b3 \ + -bitmap @[file join $tk_library demos.jp images letters.bmp] \ + -variable letters -value full + radiobutton $w.frame.left.b4 \ + -bitmap @[file join $tk_library demos.jp images noletter.bmp] \ + -variable letters -value empty + pack $w.frame.left.b3 $w.frame.left.b4 -side top -expand yes diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/image1.tcl ./library/demos.jp/image1.tcl *** ../../tk8.0.5/library/demos.jp/image1.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/image1.tcl Thu Apr 1 00:08:33 1999 *************** *** 0 **** --- 1,38 ---- + # image1.tcl -- + # + # This demonstration script displays two image widgets. + # + # RCS: @(#) $Id: image1.tcl,v 1.1 1999/03/31 15:08:33 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .image1 + catch {destroy $w} + toplevel $w + wm title $w "Image Demonstration #1" + wm iconname $w "Image1" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "This demonstration displays two images, each in a separate label widget." \ + "$B$3$N%G%b$G$O(B 2 $B$D$N%i%Y%k>e$K2hA|$r$=$l$>$lI=<($7$F$$$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + catch {image delete image1a} + image create photo image1a -file [file join $tk_library demos.jp images earth.gif] + label $w.l1 -image image1a -bd 1 -relief sunken + + catch {image delete image1b} + image create photo image1b \ + -file [file join $tk_library demos.jp images earthris.gif] + label $w.l2 -image image1b -bd 1 -relief sunken + + pack $w.l1 $w.l2 -side top -padx .5m -pady .5m diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/image2.tcl ./library/demos.jp/image2.tcl *** ../../tk8.0.5/library/demos.jp/image2.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/image2.tcl Thu Apr 1 00:08:33 1999 *************** *** 0 **** --- 1,82 ---- + # image2.tcl -- + # + # This demonstration script creates a simple collection of widgets + # that allow you to select and view images in a Tk label. + # + # RCS: @(#) $Id: image2.tcl,v 1.1 1999/03/31 15:08:33 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # loadDir -- + # This procedure reloads the directory listbox from the directory + # named in the demo's entry. + # + # Arguments: + # w - Name of the toplevel window of the demo. + + proc loadDir w { + global dirName + + $w.f.list delete 0 end + foreach i [lsort [glob [file join $dirName *]]] { + $w.f.list insert end [file tail $i] + } + } + + # loadImage -- + # Given the name of the toplevel window of the demo and the mouse + # position, extracts the directory entry under the mouse and loads + # that file into a photo image for display. + # + # Arguments: + # w - Name of the toplevel window of the demo. + # x, y- Mouse position within the listbox. + + proc loadImage {w x y} { + global dirName + + set file [file join $dirName [$w.f.list get @$x,$y]] + image2a configure -file $file + } + + set w .image2 + catch {destroy $w} + toplevel $w + wm title $w "Image Demonstration #2" + wm iconname $w "Image2" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "This demonstration allows you to view images using a Tk \"photo\" image. First type a directory name in the listbox, then type Return to load the directory into the listbox. Then double-click on a file name in the listbox to see that image." \ + "$B$3$N%G%b$G$O(BTk $B$N(Bphoto image $B$r;HMQ$7$F2hA|$r8+$k$3$H$,$G$-$^$9!#:G=i$K%(%s%H%jFb$K%G%#%l%/%H%jL>$rF~$l$F2<$5$$!#$r%@%V%k%/%j%C%/$7$F2<$5$$!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + label $w.dirLabel -text [langSel "Directory:" "$B%G%#%l%/%H%j(B:"] + set dirName [file join $tk_library demos.jp images] + entry $w.dirName -width 30 -textvariable dirName + bind $w.dirName "loadDir $w" + frame $w.spacer1 -height 3m -width 20 + label $w.fileLabel -text [langSel "File:" "$B%U%!%$%k(B:"] + frame $w.f + pack $w.dirLabel $w.dirName $w.spacer1 $w.fileLabel $w.f -side top -anchor w + + listbox $w.f.list -width 20 -height 10 -yscrollcommand "$w.f.scroll set" + scrollbar $w.f.scroll -command "$w.f.list yview" + pack $w.f.list $w.f.scroll -side left -fill y -expand 1 + $w.f.list insert 0 earth.gif earthris.gif teapot.ppm + bind $w.f.list "loadImage $w %x %y" + + catch {image delete image2a} + image create photo image2a + frame $w.spacer2 -height 3m -width 20 + label $w.imageLabel -text [langSel "Image:" "$B2hA|(B:"] + label $w.image -image image2a + pack $w.spacer2 $w.imageLabel $w.image -side top -anchor w diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/items.tcl ./library/demos.jp/items.tcl *** ../../tk8.0.5/library/demos.jp/items.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/items.tcl Thu Apr 1 00:08:34 1999 *************** *** 0 **** --- 1,293 ---- + # items.tcl -- + # + # This demonstration script creates a canvas that displays the + # canvas item types. + # + # RCS: @(#) $Id: items.tcl,v 1.1 1999/03/31 15:08:34 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .items + catch {destroy $w} + toplevel $w + wm title $w "Canvas Item Demonstration" + wm iconname $w "Items" + positionWindow $w + set c $w.frame.c + + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "This window contains a canvas widget with examples of the various kinds of items supported by canvases. The following operations are supported:\n Button-1 drag:\tmoves item under pointer.\n Button-2 drag:\trepositions view.\n Button-3 drag:\tstrokes out area.\n Ctrl+f:\t\tprints items under area." \ + "$B$3$N%&%#%s%I%&$K$O%-%c%s%P%9(B widget $B$,F~$C$F$*$j!"$=$NCf$K$O%-%c%s%P%9(B widget $B$,%5%]!<%H$9$kMM!9$J%?%$%W$N%"%$%F%`$NNc$,F~$C$F$$$^$9!#H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame + pack $w.frame -side top -fill both -expand yes + + canvas $c -scrollregion {0c 0c 30c 24c} -width 15c -height 10c \ + -relief sunken -borderwidth 2 \ + -xscrollcommand "$w.frame.hscroll set" \ + -yscrollcommand "$w.frame.vscroll set" + scrollbar $w.frame.vscroll -command "$c yview" + scrollbar $w.frame.hscroll -orient horiz -command "$c xview" + + grid $c -in $w.frame \ + -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid $w.frame.vscroll \ + -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news + grid $w.frame.hscroll \ + -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid rowconfig $w.frame 0 -weight 1 -minsize 0 + grid columnconfig $w.frame 0 -weight 1 -minsize 0 + + # Display a 3x3 rectangular grid. + + $c create rect 0c 0c 30c 24c -width 2 + $c create line 0c 8c 30c 8c -width 2 + $c create line 0c 16c 30c 16c -width 2 + $c create line 10c 0c 10c 24c -width 2 + $c create line 20c 0c 20c 24c -width 2 + + set font1 {Helvetica12} + set font2 {Helvetica24bold} + if {[winfo depth $c] > 1} { + set blue DeepSkyBlue3 + set red red + set bisque bisque3 + set green SeaGreen3 + } else { + set blue black + set red black + set bisque black + set green black + } + + # Set up demos within each of the areas of the grid. + + $c create text 5c .2c -text [langSel Lines $B%i%$%s(B] -anchor n + $c create line 1c 1c 3c 1c 1c 4c 3c 4c -width 2m -fill $blue \ + -cap butt -join miter -tags item + $c create line 4.67c 1c 4.67c 4c -arrow last -tags item + $c create line 6.33c 1c 6.33c 4c -arrow both -tags item + $c create line 5c 6c 9c 6c 9c 1c 8c 1c 8c 4.8c 8.8c 4.8c 8.8c 1.2c \ + 8.2c 1.2c 8.2c 4.6c 8.6c 4.6c 8.6c 1.4c 8.4c 1.4c 8.4c 4.4c \ + -width 3 -fill $red -tags item + $c create line 1c 5c 7c 5c 7c 7c 9c 7c -width .5c \ + -stipple @[file join $tk_library demos.jp images gray25.bmp] \ + -arrow both -arrowshape {15 15 7} -tags item + $c create line 1c 7c 1.75c 5.8c 2.5c 7c 3.25c 5.8c 4c 7c -width .5c \ + -cap round -join round -tags item + + $c create text 15c .2c -text [langSel "Curves (smoothed lines)" "$B6J@~(B ($B3j$i$+$K$D$J$$$@D>@~(B)"] -anchor n + $c create line 11c 4c 11.5c 1c 13.5c 1c 14c 4c -smooth on \ + -fill $blue -tags item + $c create line 15.5c 1c 19.5c 1.5c 15.5c 4.5c 19.5c 4c -smooth on \ + -arrow both -width 3 -tags item + $c create line 12c 6c 13.5c 4.5c 16.5c 7.5c 18c 6c \ + 16.5c 4.5c 13.5c 7.5c 12c 6c -smooth on -width 3m -cap round \ + -stipple @[file join $tk_library demos.jp images gray25.bmp] \ + -fill $red -tags item + + $c create text 25c .2c -text [langSel Polygons $BB?3Q7A(B] -anchor n + $c create polygon 21c 1.0c 22.5c 1.75c 24c 1.0c 23.25c 2.5c \ + 24c 4.0c 22.5c 3.25c 21c 4.0c 21.75c 2.5c -fill $green \ + -outline black -width 4 -tags item + $c create polygon 25c 4c 25c 4c 25c 1c 26c 1c 27c 4c 28c 1c \ + 29c 1c 29c 4c 29c 4c -fill $red -smooth on -tags item + $c create polygon 22c 4.5c 25c 4.5c 25c 6.75c 28c 6.75c \ + 28c 5.25c 24c 5.25c 24c 6.0c 26c 6c 26c 7.5c 22c 7.5c \ + -stipple @[file join $tk_library demos.jp images gray25.bmp] \ + -outline black -tags item + + $c create text 5c 8.2c -text [langSel Rectangles $B6k7A(B] -anchor n + $c create rectangle 1c 9.5c 4c 12.5c -outline $red -width 3m -tags item + $c create rectangle 0.5c 13.5c 4.5c 15.5c -fill $green -tags item + $c create rectangle 6c 10c 9c 15c -outline {} \ + -stipple @[file join $tk_library demos.jp images gray25.bmp] \ + -fill $blue -tags item + + $c create text 15c 8.2c -text [langSel Ovals $BBJ1_(B] -anchor n + $c create oval 11c 9.5c 14c 12.5c -outline $red -width 3m -tags item + $c create oval 10.5c 13.5c 14.5c 15.5c -fill $green -tags item + $c create oval 16c 10c 19c 15c -outline {} \ + -stipple @[file join $tk_library demos.jp images gray25.bmp] \ + -fill $blue -tags item + + $c create text 25c 8.2c -text [langSel Text $B%F%-%9%H(B] -anchor n + $c create rectangle 22.4c 8.9c 22.6c 9.1c + $c create text 22.5c 9c -anchor n -font $font1 -width 4c \ + -text [langSel "A short string of text, word-wrapped, justified left, and anchored north (at the top). The rectangles show the anchor points for each piece of text." \ + "$BC;$$%F%-%9%H!#%o!<%I%i%C%W!":8B7$(!"%"%s%+!<$OKL(B ($B>e(B)$B!#""$O3F%F%-%9%H$N%"%s%+!<%]%$%s%H$r<($9!#(B"] -tags item + $c create rectangle 25.4c 10.9c 25.6c 11.1c + $c create text 25.5c 11c -anchor w -font $font1 -fill $blue \ + -text [langSel "Several lines,\n each centered\nindividually,\nand all anchored\nat the left edge." \ + "$B$$$/$D$+$N9T!#(B\n$B$=$l$>$lFHN)$K(B\n$B9TB7$(!#(B\n$BA4$F:8C<$,(B\n$B%"%s%+!<$5$l$F$$$k!#(B"] \ + -justify center -tags item + $c create rectangle 24.9c 13.9c 25.1c 14.1c + $c create text 25c 14c -font $font2 -anchor c -fill $red -stipple gray50 \ + -text [langSel "Stippled characters" "$BLV3]J8;z(B"] -tags item + + $c create text 5c 16.2c -text [langSel Arcs $B8L(B] -anchor n + $c create arc 0.5c 17c 7c 20c -fill $green -outline black \ + -start 45 -extent 270 -style pieslice -tags item + $c create arc 6.5c 17c 9.5c 20c -width 4m -style arc \ + -outline $blue -start -135 -extent 270 -tags item \ + -outlinestipple @[file join $tk_library demos.jp images gray25.bmp] + $c create arc 0.5c 20c 9.5c 24c -width 4m -style pieslice \ + -fill {} -outline $red -start 225 -extent -90 -tags item + $c create arc 5.5c 20.5c 9.5c 23.5c -width 4m -style chord \ + -fill $blue -outline {} -start 45 -extent 270 -tags item + + $c create text 15c 16.2c -text [langSel Bitmaps $B%S%C%H%^%C%W(B] -anchor n + $c create bitmap 13c 20c -tags item \ + -bitmap @[file join $tk_library demos.jp images face.bmp] + $c create bitmap 17c 18.5c -tags item \ + -bitmap @[file join $tk_library demos.jp images noletter.bmp] + $c create bitmap 17c 21.5c -tags item \ + -bitmap @[file join $tk_library demos.jp images letters.bmp] + + $c create text 25c 16.2c -text [langSel Windows $B%&%#%s%I%&(B] -anchor n + button $c.button -text [langSel "Press Me" "$B2!$7$F$M(B"] -command "butPress $c $red" + $c create window 21c 18c -window $c.button -anchor nw -tags item + entry $c.entry -width 20 -relief sunken + $c.entry insert end [langSel "Edit this text" "$BJT=8$7$F$M(B"] + $c create window 21c 21c -window $c.entry -anchor nw -tags item + scale $c.scale -from 0 -to 100 -length 6c -sliderlength .4c \ + -width .5c -tickinterval 0 + $c create window 28.5c 17.5c -window $c.scale -anchor n -tags item + $c create text 21c 17.9c -text [langSel Button: $B%\%?%s(B:] -anchor sw + $c create text 21c 20.9c -text [langSel Entry: $B%(%s%H%j(B:] -anchor sw + $c create text 28.5c 17.4c -text [langSel Scale: $B%9%1!<%k(B:] -anchor s + + # Set up event bindings for canvas: + + $c bind item "itemEnter $c" + $c bind item "itemLeave $c" + bind $c <2> "$c scan mark %x %y" + bind $c "$c scan dragto %x %y" + bind $c <3> "itemMark $c %x %y" + bind $c "itemStroke $c %x %y" + bind $c "itemsUnderArea $c" + bind $c <1> "itemStartDrag $c %x %y" + bind $c "itemDrag $c %x %y" + + # Utility procedures for highlighting the item under the pointer: + + proc itemEnter {c} { + global restoreCmd + + if {[winfo depth $c] == 1} { + set restoreCmd {} + return + } + set type [$c type current] + if {$type == "window"} { + set restoreCmd {} + return + } + if {$type == "bitmap"} { + set bg [lindex [$c itemconf current -background] 4] + set restoreCmd [list $c itemconfig current -background $bg] + $c itemconfig current -background SteelBlue2 + return + } + set fill [lindex [$c itemconfig current -fill] 4] + if {(($type == "rectangle") || ($type == "oval") || ($type == "arc")) + && ($fill == "")} { + set outline [lindex [$c itemconfig current -outline] 4] + set restoreCmd "$c itemconfig current -outline $outline" + $c itemconfig current -outline SteelBlue2 + } else { + set restoreCmd "$c itemconfig current -fill $fill" + $c itemconfig current -fill SteelBlue2 + } + } + + proc itemLeave {c} { + global restoreCmd + + eval $restoreCmd + } + + # Utility procedures for stroking out a rectangle and printing what's + # underneath the rectangle's area. + + proc itemMark {c x y} { + global areaX1 areaY1 + set areaX1 [$c canvasx $x] + set areaY1 [$c canvasy $y] + $c delete area + } + + proc itemStroke {c x y} { + global areaX1 areaY1 areaX2 areaY2 + set x [$c canvasx $x] + set y [$c canvasy $y] + if {($areaX1 != $x) && ($areaY1 != $y)} { + $c delete area + $c addtag area withtag [$c create rect $areaX1 $areaY1 $x $y \ + -outline black] + set areaX2 $x + set areaY2 $y + } + } + + proc itemsUnderArea {c} { + global areaX1 areaY1 areaX2 areaY2 + set area [$c find withtag area] + set items "" + foreach i [$c find enclosed $areaX1 $areaY1 $areaX2 $areaY2] { + if {[lsearch [$c gettags $i] item] != -1} { + lappend items $i + } + } + puts stdout "Items enclosed by area: $items" + set items "" + foreach i [$c find overlapping $areaX1 $areaY1 $areaX2 $areaY2] { + if {[lsearch [$c gettags $i] item] != -1} { + lappend items $i + } + } + puts stdout "Items overlapping area: $items" + } + + set areaX1 0 + set areaY1 0 + set areaX2 0 + set areaY2 0 + + # Utility procedures to support dragging of items. + + proc itemStartDrag {c x y} { + global lastX lastY + set lastX [$c canvasx $x] + set lastY [$c canvasy $y] + } + + proc itemDrag {c x y} { + global lastX lastY + set x [$c canvasx $x] + set y [$c canvasy $y] + $c move current [expr $x-$lastX] [expr $y-$lastY] + set lastX $x + set lastY $y + } + + # Procedure that's invoked when the button embedded in the canvas + # is invoked. + + proc butPress {w color} { + set i [$w create text 25c 18.1c -text [langSel "Ouch!!" "$B$$$F$F(B!!"] -fill $color -anchor n] + after 500 "$w delete $i" + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/ixset ./library/demos.jp/ixset *** ../../tk8.0.5/library/demos.jp/ixset Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/ixset Thu Apr 1 00:08:34 1999 *************** *** 0 **** --- 1,312 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # ixset -- + # A nice interface to "xset" to change X server settings + # + # History : + # 91/11/23 : pda@masi.ibp.fr, jt@ratp.fr : design + # 92/08/01 : pda@masi.ibp.fr : cleaning + # + # RCS: @(#) $Id: ixset,v 1.1 1999/03/31 15:08:34 m-hirano Exp $ + + # + # Button actions + # + + proc quit {} { + destroy . + } + + proc ok {} { + writesettings + quit + } + + proc cancel {} { + readsettings + dispsettings + } + + # apply is just "writesettings" + + + # + # Read current settings + # + + proc readsettings {} { + global kbdrep ; set kbdrep "on" + global kbdcli ; set kbdcli 0 + global bellvol ; set bellvol 100 + global bellpit ; set bellpit 440 + global belldur ; set belldur 100 + global mouseacc ; set mouseacc "3/1" + global mousethr ; set mousethr 4 + global screenbla ; set screenbla "blank" + global screentim ; set screentim 600 + global screencyc ; set screencyc 600 + + set xfd [open "|xset q" r] + while {[gets $xfd line] > -1} { + set kw [lindex $line 0] + + case $kw in { + {auto} + { + set rpt [lindex $line 1] + if {[expr "{$rpt} == {repeat:}"]} then { + set kbdrep [lindex $line 2] + set kbdcli [lindex $line 6] + } + } + {bell} + { + set bellvol [lindex $line 2] + set bellpit [lindex $line 5] + set belldur [lindex $line 8] + } + {acceleration:} + { + set mouseacc [lindex $line 1] + set mousethr [lindex $line 3] + } + {prefer} + { + set bla [lindex $line 2] + set screenbla [expr "{$bla} == {yes} ? {blank} : {noblank}"] + } + {timeout:} + { + set screentim [lindex $line 1] + set screencyc [lindex $line 3] + } + } + } + close $xfd + + # puts stdout [format "Key REPEAT = %s\n" $kbdrep] + # puts stdout [format "Key CLICK = %s\n" $kbdcli] + # puts stdout [format "Bell VOLUME = %s\n" $bellvol] + # puts stdout [format "Bell PITCH = %s\n" $bellpit] + # puts stdout [format "Bell DURATION = %s\n" $belldur] + # puts stdout [format "Mouse ACCELERATION = %s\n" $mouseacc] + # puts stdout [format "Mouse THRESHOLD = %s\n" $mousethr] + # puts stdout [format "Screen BLANCK = %s\n" $screenbla] + # puts stdout [format "Screen TIMEOUT = %s\n" $screentim] + # puts stdout [format "Screen CYCLE = %s\n" $screencyc] + } + + + # + # Write settings into the X server + # + + proc writesettings {} { + global kbdrep kbdcli bellvol bellpit belldur + global mouseacc mousethr screenbla screentim screencyc + + set bellvol [.bell.vol get] + set bellpit [.bell.val.pit.entry get] + set belldur [.bell.val.dur.entry get] + + if {[expr "{$kbdrep} == {on}"]} then { + set kbdcli [.kbd.val.cli get] + } else { + set kbdcli "off" + } + + set mouseacc [.mouse.hor.acc.entry get] + set mousethr [.mouse.hor.thr.entry get] + + set screentim [.screen.val.le.tim.entry get] + set screencyc [.screen.val.le.cyc.entry get] + + exec xset \ + b $bellvol $bellpit $belldur \ + c $kbdcli \ + r $kbdrep \ + m $mouseacc $mousethr \ + s $screentim $screencyc \ + s $screenbla + } + + + # + # Sends all settings to the window + # + + proc dispsettings {} { + global kbdrep kbdcli bellvol bellpit belldur + global mouseacc mousethr screenbla screentim screencyc + + .bell.vol set $bellvol + .bell.val.pit.entry delete 0 end + .bell.val.pit.entry insert 0 $bellpit + .bell.val.dur.entry delete 0 end + .bell.val.dur.entry insert 0 $belldur + + .kbd.val.onoff [expr "{$kbdrep} == {on} ? {select} : {deselect}"] + .kbd.val.cli set $kbdcli + + .mouse.hor.acc.entry delete 0 end + .mouse.hor.acc.entry insert 0 $mouseacc + .mouse.hor.thr.entry delete 0 end + .mouse.hor.thr.entry insert 0 $mousethr + + .screen.val.rb.blank [expr "{$screenbla}=={blank} ? {select} : {deselect}"] + .screen.val.rb.pat [expr "{$screenbla}!={blank} ? {select} : {deselect}"] + .screen.val.le.tim.entry delete 0 end + .screen.val.le.tim.entry insert 0 $screentim + .screen.val.le.cyc.entry delete 0 end + .screen.val.le.cyc.entry insert 0 $screencyc + } + + + # + # Create all windows, and pack them + # + + proc labelentry {path text length} { + frame $path + label $path.label -text $text + entry $path.entry -width $length -relief sunken + pack $path.label -side left -expand y + pack $path.entry -side right -expand y + } + + proc createwindows {} { + # + # Buttons + # + + frame .buttons + button .buttons.ok -command "ok" -text "Ok" + button .buttons.apply -command "writesettings" -text "Apply" + button .buttons.cancel -command "cancel" -text "Cancel" + button .buttons.quit -command "quit" -text "Quit" + + pack .buttons.ok .buttons.apply .buttons.cancel .buttons.quit \ + -side left -expand yes -pady 5 + + # + # Bell settings + # + + frame .bell -relief raised -borderwidth 2 + label .bell.label -text "Bell Settings" + scale .bell.vol \ + -from 0 -to 100 -length 200 -tickinterval 20 \ + -label "Volume (%)" -orient horizontal + + frame .bell.val + labelentry .bell.val.pit "Pitch (Hz)" 6 + labelentry .bell.val.dur "Duration (ms)" 6 + pack .bell.val.pit -side left -padx 5 + pack .bell.val.dur -side right -padx 5 + pack .bell.label .bell.vol .bell.val -side top -expand yes + + # + # Keyboard settings + # + + frame .kbd -relief raised -borderwidth 2 + + label .kbd.label -text "Keyboard Repeat Settings" + + frame .kbd.val + checkbutton .kbd.val.onoff \ + -text "On" \ + -onvalue "on" -offvalue "off" -variable kbdrep \ + -relief flat + scale .kbd.val.cli \ + -from 0 -to 100 -length 200 -tickinterval 20 \ + -label "Click Volume (%)" -orient horizontal + pack .kbd.val.onoff -side left -expand yes -fill both + pack .kbd.val.cli -side left -expand yes + + pack .kbd.label -side top -expand yes + pack .kbd.val -side top -expand yes -pady 2 -fill x + + # + # Mouse settings + # + + frame .mouse -relief raised -borderwidth 2 + + label .mouse.label -text "Mouse Settings" + frame .mouse.hor + labelentry .mouse.hor.acc "Acceleration" 3 + labelentry .mouse.hor.thr "Threshold (pixels)" 3 + + pack .mouse.hor.acc -side left + pack .mouse.hor.thr -side right + + pack .mouse.label -side top + pack .mouse.hor -side top -expand yes + + # + # Screen Saver settings + # + + frame .screen -relief raised -borderwidth 2 + + label .screen.label -text "Screen-saver Settings" + frame .screen.val + + frame .screen.val.rb + radiobutton .screen.val.rb.blank \ + -variable screenblank -text "Blank" -relief flat \ + -value "blank" -variable screenbla + radiobutton .screen.val.rb.pat \ + -variable screenblank -text "Pattern" -relief flat \ + -value "noblank" -variable screenbla + pack .screen.val.rb.blank .screen.val.rb.pat -side top -pady 2 -anchor w + frame .screen.val.le + labelentry .screen.val.le.tim "Timeout (s)" 5 + labelentry .screen.val.le.cyc "Cycle (s)" 5 + pack .screen.val.le.tim .screen.val.le.cyc -side top -pady 2 -anchor e + + pack .screen.val.rb .screen.val.le -side left + + pack .screen.label -side top + pack .screen.val -side top -expand y + + # + # Main window + # + + pack .buttons -side top -fill both + pack .bell .kbd .mouse .screen -side top -fill both -ipady 5 -expand yes + + # + # Let the user resize our window + # + wm minsize . 10 10 + } + + ############################################################################## + # Main program + + # + # Listen what "xset" tells us... + # + + readsettings + + # + # Create all windows + # + + createwindows + + # + # Write xset parameters + # + + dispsettings + + # + # Now, wait for user actions... + # diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/label.tcl ./library/demos.jp/label.tcl *** ../../tk8.0.5/library/demos.jp/label.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/label.tcl Thu Apr 1 00:08:35 1999 *************** *** 0 **** --- 1,42 ---- + # label.tcl -- + # + # This demonstration script creates a toplevel window containing + # several label widgets. + # + # RCS: @(#) $Id: label.tcl,v 1.1 1999/03/31 15:08:35 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .label + catch {destroy $w} + toplevel $w + wm title $w "Label Demonstration" + wm iconname $w "label" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "Five labels are displayed below: three textual ones on the left, and a bitmap label and a text label on the right. Labels are pretty boring because you can't do anything with them." \ + "$B2<$K$O(B 5$B$D$N%i%Y%k$,I=<($5$l$F$$$^$9!#:8B&$K$O%F%-%9%H%i%Y%k$,(B 3$B$D$"$j!"1&B&$K$O%S%C%H%^%C%W%i%Y%k$H%F%-%9%H%i%Y%k$,$"$j$^$9!#%i%Y%k$H$$$&$N$O$"$^$jLLGr$$$b$N$G$O$"$j$^$;$s!#$J$<$J$iD/$a$k0J302?$b$G$-$J$$$+$i$G$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.left + frame $w.right + pack $w.left $w.right -side left -expand yes -padx 10 -pady 10 -fill both + + label $w.left.l1 -text [langSel "First label" "$B:G=i$N%i%Y%k(B"] + label $w.left.l2 -text [langSel "Second label, raised" "2 $BHVL\!#$A$g$C$HIb$->e$,$i$;$F$_$^$7$?(B"] -relief raised + label $w.left.l3 -text [langSel "Third label, sunken" "3 $BHVL\!#D@$s$G$$$^$9(B"] -relief sunken + pack $w.left.l1 $w.left.l2 $w.left.l3 -side top -expand yes -pady 2 -anchor w + + label $w.right.bitmap -borderwidth 2 -relief sunken \ + -bitmap @[file join $tk_library demos.jp images face.bmp] + label $w.right.caption -text [langSel "Tcl/Tk Proprietor" "Tcl/Tk $B=jM-l9g$O!"$=$N%"%/%;%i%l!<%?$rF~NO$9$k$3$H$G%a%K%e!<$r;XDj$9$k$3$H$J$7$KH(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + menu $w.menu -tearoff 0 + + set m $w.menu.file + menu $m -tearoff 0 + $w.menu add cascade -label [langSel "File" "$B%U%!%$%k(B(F)"] -menu $m -underline [langSel 0 5] + $m add command -label [langSel "Open..." "$B3+$/(B ..."] -command { + error [langSel \ + "this is just a demo: no action has been defined for the \"Open...\" entry" \ + "$B$3$l$O!"%G%b$G$9$N$G(B\"$B3+$/(B ...\"$B$KBP$9$k%"%/%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B"] + } + $m add command -label [langSel "New" "$B?75,(B"] -command { + error [langSel \ + "this is just a demo: no action has been defined for the \"New\" entry" \ + "$B$3$l$O!"%G%b$G$9$N$G(B\"$B?75,(B ...\"$B$KBP$9$k%"%/%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B"] + } + $m add command -label [langSel "Save" "$BJ]B8(B"] -command { + error [langSel \ + "this is just a demo: no action has been defined for the \"Save\" entry" \ + "$B$3$l$O!"%G%b$G$9$N$G(B\"$BJ]B8(B ...\"$B$KBP$9$k%"%/%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B"] + } + $m add command -label [langSel "Save As..." "$BL>A0$rIU$1$FJ]B8(B ..."] -command { + error [langSel \ + "this is just a demo: no action has been defined for the \"Save As...\" entry" \ + "$B$3$l$O!"%G%b$G$9$N$G(B\"$BL>A0$rIU$1$FJ]B8(B ...\"$B$KBP$9$k%"%/%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B"] + } + $m add separator + $m add command -label [langSel "Print Setup..." "$B0u:~@_Dj(B ..."] -command { + error [langSel \ + "this is just a demo: no action has been defined for the \"Print Setup...\" entry" \ + "$B$3$l$O!"%G%b$G$9$N$G(B\"$B0u:~@_Dj(B ...\"$B$KBP$9$k%"%/%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B"] + } + $m add command -label [langSel "Print..." "$B0u:~(B ..."] -command { + error [langSel \ + "this is just a demo: no action has been defined for the \"Print...\" entry" \ + "$B$3$l$O!"%G%b$G$9$N$G(B\"$B0u:~(B ...\"$B$KBP$9$k%"%/%7%g%s$ODj5A$5$l$F$$$^$;$s!#(B"] + } + $m add separator + $m add command -label [langSel "Dismiss Menus Demo" "$B%a%K%e!<%G%bCf;_(B"] -command "destroy $w" + + set m $w.menu.basic + $w.menu add cascade -label [langSel "Basic" "$B4pK\(B(B)"] -menu $m -underline [langSel 0 3] + menu $m -tearoff 0 + $m add command -label [langSel "Long entry that does nothing" "$B2?$b$7$J$$D9$$%(%s%H%j(B"] + if {$tcl_platform(platform) == "macintosh"} { + set modifier Command + } elseif {$tcl_platform(platform) == "windows"} { + set modifier Control + } else { + set modifier Meta + } + foreach i {A B C D E F} { + $m add command -label [langSel "Print letter \"$i\"" "$BJ8;z(B\"$i\"$B$r0u;z(B"] -underline [langSel 14 3] \ + -accelerator Meta+$i -command "puts $i" -accelerator $modifier+$i + bind $w <$modifier-[string tolower $i]> "puts $i" + } + + set m $w.menu.cascade + $w.menu add cascade -label [langSel "Cascades" "$B%+%9%1!<%I(B(C)"] -menu $m -underline [langSel 0 6] + menu $m -tearoff 0 + $m add command -label [langSel "Print hello" "$B$3$s$K$A$O(B(H)"] \ + -command {puts stdout "Hello"} -accelerator $modifier+H -underline [langSel 6 6] + bind $w <$modifier-h> {puts stdout "Hello"} + $m add command -label [langSel "Print goodbye" "$B$5$h$&$J$i(B(G)"] -command {\ + puts stdout "Goodbye"} -accelerator $modifier+G -underline [langSel 6 6] + bind $w <$modifier-g> {puts stdout "Goodbye"} + $m add cascade -label [langSel "Check buttons" "$B%A%'%C%/%\%?%s(B(C)"] \ + -menu $w.menu.cascade.check -underline [langSel 0 8] + $m add cascade -label [langSel "Radio buttons" "$B%i%8%*%\%?%s(B(R)"] \ + -menu $w.menu.cascade.radio -underline [langSel 0 7] + + set m $w.menu.cascade.check + menu $m -tearoff 0 + $m add check -label [langSel "Oil checked" "$B%*%$%kE@8!(B"] -variable oil + $m add check -label [langSel "Transmission checked" "$B%H%i%s%9%_%C%7%g%sE@8!(B"] -variable trans + $m add check -label [langSel "Brakes checked" "$B%V%l!<%-E@8!(B"] -variable brakes + $m add check -label [langSel "Lights checked" "$B%i%$%HE@8!(B"] -variable lights + $m add separator + $m add command -label [langSel "Show current values" "$B8=:_$NCM$rI=<((B"] \ + -command "showVars $w.menu.cascade.dialog oil trans brakes lights" + $m invoke 1 + $m invoke 3 + + set m $w.menu.cascade.radio + menu $m -tearoff 0 + $m add radio -label [langSel "10 point" "10 $B%]%$%s%H(B"] -variable pointSize -value 10 + $m add radio -label [langSel "14 point" "14 $B%]%$%s%H(B"] -variable pointSize -value 14 + $m add radio -label [langSel "18 point" "18 $B%]%$%s%H(B"] -variable pointSize -value 18 + $m add radio -label [langSel "24 point" "24 $B%]%$%s%H(B"] -variable pointSize -value 24 + $m add radio -label [langSel " point" "32 $B%]%$%s%H(B"] -variable pointSize -value 32 + $m add sep + $m add radio -label [langSel "Roman" "$B%m!<%^%s(B"] -variable style -value roman + $m add radio -label [langSel "Bold" "$B%\!<%k%I(B"] -variable style -value bold + $m add radio -label [langSel "Italic" "$B%$%?%j%C%/(B"] -variable style -value italic + $m add sep + $m add command -label [langSel "Show current values" "$B8=:_$NCM$rI=<((B"] \ + -command "showVars $w.menu.cascade.dialog pointSize style" + $m invoke 1 + $m invoke 7 + + set m $w.menu.icon + $w.menu add cascade -label [langSel "Icons" "$B%"%$%3%s(B(I)"] -menu $m -underline [langSel 0 5] + menu $m -tearoff 0 + $m add command \ + -bitmap @[file join $tk_library demos.jp images pattern.bmp] \ + -hidemargin 1 \ + -command { + tk_dialog .pattern {Bitmap Menu Entry} [langSel \ + {The menu entry you invoked displays a bitmap rather than a text string. Other than this, it is just like any other menu entry.} \ + {$B:#$"$J$?$,A*Br$7$?%a%K%e!<$N9`L\$O%F%-%9%H$G$O$J$/%S%C%H%^%C%W$rI=<($7$F$$$^$7$?!#$=$l0J30$NE@$G$OB>$N%a%K%e!<9`L\$HJQ$o$j$^$;$s!#(B}] \ + {} 0 [langSel OK $BN;2r(B] + } + foreach i {info questhead error} { + $m add command -bitmap $i -command "puts {You invoked the $i bitmap}" -hidemargin 1 + } + $m entryconfigure 2 -columnbreak 1 + + set m $w.menu.more + $w.menu add cascade -label [langSel "More" "$B$=$NB>(B(M)"] -menu $m -underline [langSel 0 4] + menu $m -tearoff 0 + foreach i [langSel \ + {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Make life meaningful}} \ + {{$B%(%s%H%j(B} {$BJL$N%(%s%H%j(B} {$B2?$b$7$J$$(B} {$B$[$H$s$I2?$b$7$J$$(B} {$B?M@8$r0U5A$"$k$b$N$K(B}}] { + $m add command -label $i -command [list puts "You invoked \"$i\""] + } + + set m $w.menu.colors + $w.menu add cascade -label [langSel "Colors" "$B?'(B(O)"] -menu $m -underline [langSel 1 2] + menu $m + foreach i [langSel {red orange yellow green blue} {{$B@V(B red} {$B\t(B orange} {$B2+(B yellow} {$BNP(B green} {$B@D(B blue}}] { + $m add command -label [lindex $i 0] -background [lindex $i end] \ + -command [list puts "You invoked \"$i\""] + } + + $w configure -menu $w.menu + + bind Menu <> { + global $menustatus + if {[catch {%W entrycget active -label} label]} { + set label " " + } + set menustatus $label + update idletasks + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/menubu.tcl ./library/demos.jp/menubu.tcl *** ../../tk8.0.5/library/demos.jp/menubu.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/menubu.tcl Thu Apr 1 00:08:36 1999 *************** *** 0 **** --- 1,101 ---- + # menubutton.tcl -- + # + # This demonstration script creates a window with a bunch of menus + # and cascaded menus using menubuttons. + # + # # RCS: @(#) $Id: menubu.tcl,v 1.1 1999/03/31 15:08:36 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .menubutton + catch {destroy $w} + toplevel $w + wm title $w "Menu Button Demonstration" + wm iconname $w "menubutton" + positionWindow $w + + + frame $w.body + pack $w.body -expand 1 -fill both + + menubutton $w.body.below -text [langSel "Below" "$B2<(B(B)"] -underline [langSel 0 2] -direction below -menu $w.body.below.m -relief raised + menu $w.body.below.m -tearoff 0 + $w.body.below.m add command -label [langSel "Below menu: first item" "$B2<%a%K%e!<(B: $B:G=i$N9`L\(B"] -command "puts \"You have selected the first item from the Below menu.\"" + $w.body.below.m add command -label [langSel "Below menu: second item" "$B2<%a%K%e!<(B: 2$BHVL\$N9`L\(B"] -command "puts \"You have selected the second item from the Below menu.\"" + grid $w.body.below -row 0 -column 1 -sticky n + menubutton $w.body.right -text [langSel "Right" "$B1&(B(R)"] -underline [langSel 0 2] -direction right -menu $w.body.right.m -relief raised + menu $w.body.right.m -tearoff 0 + $w.body.right.m add command -label [langSel "Right menu: first item" "$B1&%a%K%e!<(B: $B:G=i$N9`L\(B"] -command "puts \"You have selected the first item from the Right menu.\"" + $w.body.right.m add command -label [langSel "Right menu: second item" "$B1&%a%K%e!<(B: 2$BHVL\$N9`L\(B"] -command "puts \"You have selected the second item from the Right menu.\"" + frame $w.body.center + menubutton $w.body.left -text [langSel "Left" "$B:8(B(L)"] -underline [langSel 0 2] -direction left -menu $w.body.left.m -relief raised + menu $w.body.left.m -tearoff 0 + $w.body.left.m add command -label [langSel "Left menu: first item" "$B:8%a%K%e!<(B: $B:G=i$N9`L\(B"] -command "puts \"You have selected the first item from the Left menu.\"" + $w.body.left.m add command -label [langSel "Left menu: second item" "$B:8%a%K%e!<(B: 2$BHVL\$N9`L\(B"] -command "puts \"You have selected the second item from the Left menu.\"" + grid $w.body.right -row 1 -column 0 -sticky w + grid $w.body.center -row 1 -column 1 -sticky news + grid $w.body.left -row 1 -column 2 -sticky e + menubutton $w.body.above -text [langSel "Above" "$B>e(B(A)"] -underline [langSel 0 2] -direction above -menu $w.body.above.m -relief raised + menu $w.body.above.m -tearoff 0 + $w.body.above.m add command -label [langSel "Above menu: first item" "$B>e%a%K%e!<(B: $B:G=i$N9`L\(B"] -command "puts \"You have selected the first item from the Above menu.\"" + $w.body.above.m add command -label [langSel "Above menu: second item" "$B>e%a%K%e!<(B: 2$BHVL\$N9`L\(B"] -command "puts \"You have selected the second item from the Above menu.\"" + grid $w.body.above -row 2 -column 1 -sticky s + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode .menubu" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + set body $w.body.center + label $body.label -wraplength 300 -font {Helvetica14} -justify left -text [langSel \ + "This is a demonstration of menubuttons. The \"Below\" menubutton pops its menu below the button; the \"Right\" button pops to the right, etc. There are two option menus directly below this text; one is just a standard menu and the other is a 16-color palette." \ + "$B$3$l$O%a%K%e!<%\%?%s$N%G%b$G$9!#(B\"$B2<(B\"$B%\%?%s$O%\%?%s$N2<$K!"(B\"$B1&(B\"$B%\%?%s$O1&$K!"$H$$$C$?6q9g$K%a%K%e!<$r%]%C%W%"%C%W$7$^$9!#$3$N%F%-%9%H$N$9$02<$K(B2$B$D$N%*%W%7%g%s%a%K%e!<$,$"$j!"0l$D$O$?$@$NI8=`$N%a%K%e!<$G$b$&0l$D$O(B16$B?'$N%Q%l%C%H$G$9!#(B"] + pack $body.label -side top -padx 25 -pady 25 + frame $body.buttons + pack $body.buttons -padx 25 -pady 25 + langSwitch { + tk_optionMenu $body.buttons.options menubuttonoptions one two three + set menubuttonoptions one + } { + tk_optionMenu $body.buttons.options menubuttonoptions $B$$$A(B $B$K(B $B$5$s(B + set menubuttonoptions $B$$$A(B + } + pack $body.buttons.options -side left -padx 25 -pady 25 + set m [tk_optionMenu $body.buttons.colors paletteColor Black red4 DarkGreen NavyBlue gray75 Red Green Blue gray50 Yellow Cyan Magenta White Brown DarkSeaGreen DarkViolet] + if {$tcl_platform(platform) == "macintosh"} { + set topBorderColor Black + set bottomBorderColor Black + } else { + set topBorderColor gray50 + set bottomBorderColor gray75 + } + for {set i 0} {$i <= [$m index last]} {incr i} { + set name [$m entrycget $i -label] + image create photo image_$name -height 16 -width 16 + image_$name put $topBorderColor -to 0 0 16 1 + image_$name put $topBorderColor -to 0 1 1 16 + image_$name put $bottomBorderColor -to 0 15 16 16 + image_$name put $bottomBorderColor -to 15 1 16 16 + image_$name put $name -to 1 1 15 15 + + image create photo image_${name}_s -height 16 -width 16 + image_${name}_s put Black -to 0 0 16 2 + image_${name}_s put Black -to 0 2 2 16 + image_${name}_s put Black -to 2 14 16 16 + image_${name}_s put Black -to 14 2 16 14 + image_${name}_s put $name -to 2 2 14 14 + + $m entryconfigure $i -image image_$name -selectimage image_${name}_s -hidemargin 1 + } + $m configure -tearoff 1 + foreach i {Black gray75 gray50 White} { + $m entryconfigure $i -columnbreak 1 + } + + pack $body.buttons.colors -side left -padx 25 -pady 25 + + + diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/msgbox.tcl ./library/demos.jp/msgbox.tcl *** ../../tk8.0.5/library/demos.jp/msgbox.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/msgbox.tcl Thu Apr 1 00:08:37 1999 *************** *** 0 **** --- 1,71 ---- + # msgbox.tcl -- + # + # This demonstration script creates message boxes of various type + # + # RCS: @(#) $Id: msgbox.tcl,v 1.1 1999/03/31 15:08:37 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .msgbox + catch {destroy $w} + toplevel $w + wm title $w "Message Box Demonstration" + wm iconname $w "messagebox" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "Choose the icon and type option of the message box. Then press the \"Message Box\" button to see the message box." \ + "$B%a%C%;!<%8%\%C%/%9$N%"%$%3%s$HH(B"] -command "showCode $w" + button $w.buttons.vars -text [langSel "Message Box" "$B%a%C%;!<%8%\%C%/%9(B"] \ + -command "showMessageBox $w" + pack $w.buttons.dismiss $w.buttons.code $w.buttons.vars -side left -expand 1 + + frame $w.left + frame $w.right + pack $w.left $w.right -side left -expand yes -fill y -pady .5c -padx .5c + + label $w.left.label -text [langSel "Icon" "$B%"%$%3%s(B"] + frame $w.left.sep -relief ridge -bd 1 -height 2 + pack $w.left.label -side top + pack $w.left.sep -side top -fill x -expand no + + set msgboxIcon info + foreach i {error info question warning} { + radiobutton $w.left.b$i -text $i -variable msgboxIcon \ + -relief flat -value $i -width 16 -anchor w + pack $w.left.b$i -side top -pady 2 -anchor w -fill x + } + + label $w.right.label -text [langSel "Type" "$BH(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + canvas $c -relief raised -width 450 -height 300 + pack $w.c -side top -fill x + + set plotFont {Helvetica18} + + $c create line 100 250 400 250 -width 2 + $c create line 100 250 100 50 -width 2 + $c create text 225 20 -text [langSel "A Simple Plot" "$B4JC1$J%W%m%C%H(B"] -font $plotFont -fill brown + + for {set i 0} {$i <= 10} {incr i} { + set x [expr {100 + ($i*30)}] + $c create line $x 250 $x 245 -width 2 + $c create text $x 254 -text [expr 10*$i] -anchor n -font $plotFont + } + for {set i 0} {$i <= 5} {incr i} { + set y [expr {250 - ($i*40)}] + $c create line 100 $y 105 $y -width 2 + $c create text 96 $y -text [expr $i*50].0 -anchor e -font $plotFont + } + + foreach point {{12 56} {20 94} {33 98} {32 120} {61 180} + {75 160} {98 223}} { + set x [expr {100 + (3*[lindex $point 0])}] + set y [expr {250 - (4*[lindex $point 1])/5}] + set item [$c create oval [expr $x-6] [expr $y-6] \ + [expr $x+6] [expr $y+6] -width 1 -outline black \ + -fill SkyBlue2] + $c addtag point withtag $item + } + + $c bind point "$c itemconfig current -fill red" + $c bind point "$c itemconfig current -fill SkyBlue2" + $c bind point <1> "plotDown $c %x %y" + $c bind point "$c dtag selected" + bind $c "plotMove $c %x %y" + + set plot(lastX) 0 + set plot(lastY) 0 + + # plotDown -- + # This procedure is invoked when the mouse is pressed over one of the + # data points. It sets up state to allow the point to be dragged. + # + # Arguments: + # w - The canvas window. + # x, y - The coordinates of the mouse press. + + proc plotDown {w x y} { + global plot + $w dtag selected + $w addtag selected withtag current + $w raise current + set plot(lastX) $x + set plot(lastY) $y + } + + # plotMove -- + # This procedure is invoked during mouse motion events. It drags the + # current item. + # + # Arguments: + # w - The canvas window. + # x, y - The coordinates of the mouse. + + proc plotMove {w x y} { + global plot + $w move selected [expr $x-$plot(lastX)] [expr $y-$plot(lastY)] + set plot(lastX) $x + set plot(lastY) $y + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/puzzle.tcl ./library/demos.jp/puzzle.tcl *** ../../tk8.0.5/library/demos.jp/puzzle.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/puzzle.tcl Thu Apr 1 00:08:38 1999 *************** *** 0 **** --- 1,75 ---- + # puzzle.tcl -- + # + # This demonstration script creates a 15-puzzle game using a collection + # of buttons. + # + # RCS: @(#) $Id: puzzle.tcl,v 1.1 1999/03/31 15:08:38 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # puzzleSwitch -- + # This procedure is invoked when the user clicks on a particular button; + # if the button is next to the empty space, it moves the button into th + # empty space. + + proc puzzleSwitch {w num} { + global xpos ypos + if {(($ypos($num) >= ($ypos(space) - .01)) + && ($ypos($num) <= ($ypos(space) + .01)) + && ($xpos($num) >= ($xpos(space) - .26)) + && ($xpos($num) <= ($xpos(space) + .26))) + || (($xpos($num) >= ($xpos(space) - .01)) + && ($xpos($num) <= ($xpos(space) + .01)) + && ($ypos($num) >= ($ypos(space) - .26)) + && ($ypos($num) <= ($ypos(space) + .26)))} { + set tmp $xpos(space) + set xpos(space) $xpos($num) + set xpos($num) $tmp + set tmp $ypos(space) + set ypos(space) $ypos($num) + set ypos($num) $tmp + place $w.frame.$num -relx $xpos($num) -rely $ypos($num) + } + } + + set w .puzzle + catch {destroy $w} + toplevel $w + wm title $w "15-Puzzle Demonstration" + wm iconname $w "15-Puzzle" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "A 15-puzzle appears below as a collection of buttons. Click on any of the pieces next to the space, and that piece will slide over the space. Continue this until the pieces are arranged in numerical order from upper-left to lower-right." \ + "$B2<$N(B 15-$B%Q%:%k$O%\%?%s$r=8$a$F$G$-$F$$$^$9!#6u$$$F$$$k=j$NNY$N%T!<%9$r%/%j%C%/$9$k$H!"$=$N%T!<%9$,$=$N6u$$$F$$$k>l=j$K%9%i%$%I$7$^$9!#$3$NA`:n$rB3$1!"%T!<%9$,$=$N?t$N=g$K>e$+$i2H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + # Special trick: select a darker color for the space by creating a + # scrollbar widget and using its trough color. + + scrollbar $w.s + frame $w.frame -width 120 -height 120 -borderwidth 2 -relief sunken \ + -bg [$w.s cget -troughcolor] + pack $w.frame -side top -pady 1c -padx 1c + destroy $w.s + + set order {3 1 6 2 5 7 15 13 4 11 8 9 14 10 12} + for {set i 0} {$i < 15} {set i [expr $i+1]} { + set num [lindex $order $i] + set xpos($num) [expr ($i%4)*.25] + set ypos($num) [expr ($i/4)*.25] + button $w.frame.$num -relief raised -text $num -highlightthickness 0 \ + -command "puzzleSwitch $w $num" + place $w.frame.$num -relx $xpos($num) -rely $ypos($num) \ + -relwidth .25 -relheight .25 + } + set xpos(space) .75 + set ypos(space) .75 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/radio.tcl ./library/demos.jp/radio.tcl *** ../../tk8.0.5/library/demos.jp/radio.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/radio.tcl Thu Apr 1 00:08:38 1999 *************** *** 0 **** --- 1,50 ---- + # radio.tcl -- + # + # This demonstration script creates a toplevel window containing + # several radiobutton widgets. + # + # RCS: @(#) $Id: radio.tcl,v 1.1 1999/03/31 15:08:38 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .radio + catch {destroy $w} + toplevel $w + wm title $w "Radiobutton Demonstration" + wm iconname $w "radio" + positionWindow $w + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "Two groups of radiobuttons are displayed below. If you click on a button then the button will become selected exclusively among all the buttons in its group. A Tcl variable is associated with each group to indicate which of the group's buttons is selected. Click the \"See Variables\" button to see the current values of the variables." \ + "$B2<$K$O(B 2$B$D$N%i%8%*%\%?%s%0%k!<%W$,I=<($5$l$F$$$^$9!#%\%?%s$r%/%j%C%/$9$k$H!"$=$N%\%?%s$@$1$,$=$N%0%k!<%W$NCf$GA*Br$5$l$^$9!#3F%0%k!<%W$KBP$7$F$=$N%0%k!<%W$NCf$N$I$N%\%?%s$,A*Br$5$l$F$$$k$+$r<($9JQ?t$,3d$jEv$F$i$l$F$$$^$9!#8=:_$NJQ?t$NCM$r8+$k$K$O!VJQ?t;2>H!W%\%?%s$r%/%j%C%/$7$F$/$@$5$$!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + button $w.buttons.vars -text [langSel "See Variables" "$BJQ?t;2>H(B"] \ + -command "showVars $w.dialog size color" + pack $w.buttons.dismiss $w.buttons.code $w.buttons.vars -side left -expand 1 + + frame $w.left + frame $w.right + pack $w.left $w.right -side left -expand yes -pady .5c -padx .5c + + foreach i {10 12 18 24} { + radiobutton $w.left.b$i -text [langSel "Point Size $i" "$B%]%$%s%H%5%$%:(B $i"] -variable size \ + -relief flat -value $i + pack $w.left.b$i -side top -pady 2 -anchor w + } + + foreach color [langSel {Red Green Blue Yellow Orange Purple} {$B@V(B(Red) $BNP(B(Green) $B@D(B(Blue) $B2+(B(Yellow) $B\t(B(Orange) $B;g(B(Purple)}] { + if {[info commands kstring] != {}} { + set lower [kstring tolower $color] + } else { + set lower [string tolower $color] + } + radiobutton $w.right.$lower -text $color -variable color \ + -relief flat -value $lower + pack $w.right.$lower -side top -pady 2 -anchor w + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/rmt ./library/demos.jp/rmt *** ../../tk8.0.5/library/demos.jp/rmt Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/rmt Thu Apr 1 00:08:38 1999 *************** *** 0 **** --- 1,205 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # rmt -- + # This script implements a simple remote-control mechanism for + # Tk applications. It allows you to select an application and + # then type commands to that application. + # + # RCS: @(#) $Id: rmt,v 1.1 1999/03/31 15:08:38 m-hirano Exp $ + + wm title . "Tk Remote Controller" + wm iconname . "Tk Remote" + wm minsize . 1 1 + + # The global variable below keeps track of the remote application + # that we're sending to. If it's an empty string then we execute + # the commands locally. + + set app "local" + + # The global variable below keeps track of whether we're in the + # middle of executing a command entered via the text. + + set executing 0 + + # The global variable below keeps track of the last command executed, + # so it can be re-executed in response to !! commands. + + set lastCommand "" + + # Create menu bar. Arrange to recreate all the information in the + # applications sub-menu whenever it is cascaded to. + + frame .menu -relief raised -bd 2 + pack .menu -side top -fill x + menubutton .menu.file -text "File" -menu .menu.file.m -underline 0 + menu .menu.file.m + .menu.file.m add cascade -label "Select Application" \ + -menu .menu.file.m.apps -underline 0 + .menu.file.m add command -label "Quit" -command "destroy ." -underline 0 + menu .menu.file.m.apps -postcommand fillAppsMenu + pack .menu.file -side left + + # Create text window and scrollbar. + + text .t -relief sunken -bd 2 -yscrollcommand ".s set" -setgrid true + scrollbar .s -command ".t yview" + pack .s -side right -fill both + pack .t -side left + + # Create a binding to forward commands to the target application, + # plus modify many of the built-in bindings so that only information + # in the current command can be deleted (can still set the cursor + # earlier in the text and select and insert; just can't delete). + + bindtags .t {.t Text . all} + bind .t { + .t mark set insert {end - 1c} + .t insert insert \n + invoke + break + } + bind .t { + catch {.t tag remove sel sel.first promptEnd} + if {[.t tag nextrange sel 1.0 end] == ""} { + if [.t compare insert < promptEnd] { + break + } + } + } + bind .t { + catch {.t tag remove sel sel.first promptEnd} + if {[.t tag nextrange sel 1.0 end] == ""} { + if [.t compare insert <= promptEnd] { + break + } + } + } + bind .t { + if [.t compare insert < promptEnd] { + break + } + } + bind .t { + if [.t compare insert < promptEnd] { + .t mark set insert promptEnd + } + } + bind .t { + if [.t compare insert < promptEnd] { + break + } + } + bind .t { + if [.t compare insert < promptEnd] { + break + } + } + bind .t { + if [.t compare insert <= promptEnd] { + break + } + } + bind .t { + if [.t compare insert <= promptEnd] { + break + } + } + auto_load tkTextInsert + proc tkTextInsert {w s} { + if {$s == ""} { + return + } + catch { + if {[$w compare sel.first <= insert] + && [$w compare sel.last >= insert]} { + $w tag remove sel sel.first promptEnd + $w delete sel.first sel.last + } + } + $w insert insert $s + $w see insert + } + + .t tag configure bold -font {Courier 12 bold} + + # The procedure below is used to print out a prompt at the + # insertion point (which should be at the beginning of a line + # right now). + + proc prompt {} { + global app + .t insert insert "$app: " + .t mark set promptEnd {insert} + .t mark gravity promptEnd left + .t tag add bold {promptEnd linestart} promptEnd + } + + # The procedure below executes a command (it takes everything on the + # current line after the prompt and either sends it to the remote + # application or executes it locally, depending on "app". + + proc invoke {} { + global app executing lastCommand + set cmd [.t get promptEnd insert] + incr executing 1 + if [info complete $cmd] { + if {$cmd == "!!\n"} { + set cmd $lastCommand + } else { + set lastCommand $cmd + } + if {$app == "local"} { + set result [catch [list uplevel #0 $cmd] msg] + } else { + set result [catch [list send $app $cmd] msg] + } + if {$result != 0} { + .t insert insert "Error: $msg\n" + } else { + if {$msg != ""} { + .t insert insert $msg\n + } + } + prompt + .t mark set promptEnd insert + } + incr executing -1 + .t yview -pickplace insert + } + + # The following procedure is invoked to change the application that + # we're talking to. It also updates the prompt for the current + # command, unless we're in the middle of executing a command from + # the text item (in which case a new prompt is about to be output + # so there's no need to change the old one). + + proc newApp appName { + global app executing + set app $appName + if !$executing { + .t mark gravity promptEnd right + .t delete "promptEnd linestart" promptEnd + .t insert promptEnd "$appName: " + .t tag add bold "promptEnd linestart" promptEnd + .t mark gravity promptEnd left + } + return {} + } + + # The procedure below will fill in the applications sub-menu with a list + # of all the applications that currently exist. + + proc fillAppsMenu {} { + catch {.menu.file.m.apps delete 0 last} + foreach i [lsort [winfo interps]] { + .menu.file.m.apps add command -label $i -command [list newApp $i] + } + .menu.file.m.apps add command -label local -command {newApp local} + } + + set app [winfo name .] + prompt + focus .t diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/rolodex ./library/demos.jp/rolodex *** ../../tk8.0.5/library/demos.jp/rolodex Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/rolodex Thu Apr 1 00:08:39 1999 *************** *** 0 **** --- 1,196 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # rolodex -- + # This script was written as an entry in Tom LaStrange's rolodex + # benchmark. It creates something that has some of the look and + # feel of a rolodex program, although it's lifeless and doesn't + # actually do the rolodex application. + # + # RCS: @(#) $Id: rolodex,v 1.1 1999/03/31 15:08:39 m-hirano Exp $ + + foreach i [winfo child .] { + catch {destroy $i} + } + + #------------------------------------------ + # Phase 0: create the front end. + #------------------------------------------ + + frame .frame -relief flat + pack .frame -side top -fill y -anchor center + + set names {{} Name: Address: {} {} {Home Phone:} {Work Phone:} Fax:} + foreach i {1 2 3 4 5 6 7} { + frame .frame.$i + pack .frame.$i -side top -pady 2 -anchor e + + label .frame.$i.label -text [lindex $names $i] -anchor e + entry .frame.$i.entry -width 30 -relief sunken + pack .frame.$i.entry .frame.$i.label -side right + } + + frame .buttons + pack .buttons -side bottom -pady 2 -anchor center + button .buttons.clear -text Clear + button .buttons.add -text Add + button .buttons.search -text Search + button .buttons.delete -text "Delete ..." + pack .buttons.clear .buttons.add .buttons.search .buttons.delete \ + -side left -padx 2 + + #------------------------------------------ + # Phase 1: Add menus, dialog boxes + #------------------------------------------ + + frame .menu -relief raised -borderwidth 1 + pack .menu -before .frame -side top -fill x + + menubutton .menu.file -text "File" -menu .menu.file.m -underline 0 + menu .menu.file.m + .menu.file.m add command -label "Load ..." -command fileAction -underline 0 + .menu.file.m add command -label "Exit" -command {destroy .} -underline 0 + pack .menu.file -side left + + menubutton .menu.help -text "Help" -menu .menu.help.m -underline 0 + menu .menu.help.m + pack .menu.help -side right + + proc deleteAction {} { + if {[tk_dialog .delete {Confirm Action} {Are you sure?} {} 0 Cancel] + == 0} { + clearAction + } + } + .buttons.delete config -command deleteAction + + proc fileAction {} { + tk_dialog .fileSelection {File Selection} {This is a dummy file selection dialog box, which is used because there isn't a good file selection dialog built into Tk yet.} {} 0 OK + puts stderr {dummy file name} + } + + #------------------------------------------ + # Phase 3: Print contents of card + #------------------------------------------ + + proc addAction {} { + global names + foreach i {1 2 3 4 5 6 7} { + puts stderr [format "%-12s %s" [lindex $names $i] [.frame.$i.entry get]] + } + } + .buttons.add config -command addAction + + #------------------------------------------ + # Phase 4: Miscellaneous other actions + #------------------------------------------ + + proc clearAction {} { + foreach i {1 2 3 4 5 6 7} { + .frame.$i.entry delete 0 end + } + } + .buttons.clear config -command clearAction + + proc fillCard {} { + clearAction + .frame.1.entry insert 0 "John Ousterhout" + .frame.2.entry insert 0 "CS Division, Department of EECS" + .frame.3.entry insert 0 "University of California" + .frame.4.entry insert 0 "Berkeley, CA 94720" + .frame.5.entry insert 0 "private" + .frame.6.entry insert 0 "510-642-0865" + .frame.7.entry insert 0 "510-642-5775" + } + .buttons.search config -command "addAction; fillCard" + + #---------------------------------------------------- + # Phase 5: Accelerators, mnemonics, command-line info + #---------------------------------------------------- + + .buttons.clear config -text "Clear Ctrl+C" + bind . clearAction + .buttons.add config -text "Add Ctrl+A" + bind . addAction + .buttons.search config -text "Search Ctrl+S" + bind . "addAction; fillCard" + .buttons.delete config -text "Delete... Ctrl+D" + bind . deleteAction + + .menu.file.m entryconfig 1 -accel Ctrl+F + bind . fileAction + .menu.file.m entryconfig 2 -accel Ctrl+Q + bind . {destroy .} + + focus .frame.1.entry + + #---------------------------------------------------- + # Phase 6: help + #---------------------------------------------------- + + proc Help {topic {x 0} {y 0}} { + global helpTopics helpCmds + if {$topic == ""} return + while {[info exists helpCmds($topic)]} { + set topic [eval $helpCmds($topic)] + } + if [info exists helpTopics($topic)] { + set msg $helpTopics($topic) + } else { + set msg "Sorry, but no help is available for this topic" + } + tk_dialog .help {Rolodex Help} "Information on $topic:\n\n$msg" \ + {} 0 OK + } + + proc getMenuTopic {w x y} { + return $w.[$w index @[expr $y-[winfo rooty $w]]] + } + + bind . {Help [winfo containing %X %Y] %X %Y} + bind . {Help [winfo containing %X %Y] %X %Y} + + # Help text and commands follow: + + set helpTopics(.menu.file) {This is the "file" menu. It can be used to invoke some overall operations on the rolodex applications, such as loading a file or exiting.} + + set helpCmds(.menu.file.m) {getMenuTopic $topic $x $y} + set helpTopics(.menu.file.m.0) {The "Load" entry in the "File" menu posts a dialog box that you can use to select a rolodex file} + set helpTopics(.menu.file.m.1) {The "Exit" entry in the "File" menu causes the rolodex application to terminate} + set helpCmds(.menu.file.m.none) {set topic ".menu.file"} + + set helpTopics(.frame.1.entry) {In this field of the rolodex entry you should type the person's name} + set helpTopics(.frame.2.entry) {In this field of the rolodex entry you should type the first line of the person's address} + set helpTopics(.frame.3.entry) {In this field of the rolodex entry you should type the second line of the person's address} + set helpTopics(.frame.4.entry) {In this field of the rolodex entry you should type the third line of the person's address} + set helpTopics(.frame.5.entry) {In this field of the rolodex entry you should type the person's home phone number, or "private" if the person doesn't want his or her number publicized} + set helpTopics(.frame.6.entry) {In this field of the rolodex entry you should type the person's work phone number} + set helpTopics(.frame.7.entry) {In this field of the rolodex entry you should type the phone number for the person's FAX machine} + + set helpCmds(.frame.1.label) {set topic .frame.1.entry} + set helpCmds(.frame.2.label) {set topic .frame.2.entry} + set helpCmds(.frame.3.label) {set topic .frame.3.entry} + set helpCmds(.frame.4.label) {set topic .frame.4.entry} + set helpCmds(.frame.5.label) {set topic .frame.5.entry} + set helpCmds(.frame.6.label) {set topic .frame.6.entry} + set helpCmds(.frame.7.label) {set topic .frame.7.entry} + + set helpTopics(context) {Unfortunately, this application doesn't support context-sensitive help in the usual way, because when this demo was written Tk didn't have a grab mechanism and this is needed for context-sensitive help. Instead, you can achieve much the same effect by simply moving the mouse over the window you're curious about and pressing the Help or F1 keys. You can do this anytime.} + set helpTopics(help) {This application provides only very crude help. Besides the entries in this menu, you can get help on individual windows by moving the mouse cursor over the window and pressing the Help or F1 keys.} + set helpTopics(window) {This window is a dummy rolodex application created as part of Tom LaStrange's toolkit benchmark. It doesn't really do anything useful except to demonstrate a few features of the Tk toolkit.} + set helpTopics(keys) "The following accelerator keys are defined for this application (in addition to those already available for the entry windows):\n\nCtrl+A:\t\tAdd\nCtrl+C:\t\tClear\nCtrl+D:\t\tDelete\nCtrl+F:\t\tEnter file name\nCtrl+Q:\t\tExit application (quit)\nCtrl+S:\t\tSearch (dummy operation)" + set helpTopics(version) {This is version 1.0.} + + # Entries in "Help" menu + + .menu.help.m add command -label "On Context..." -command {Help context} \ + -underline 3 + .menu.help.m add command -label "On Help..." -command {Help help} \ + -underline 3 + .menu.help.m add command -label "On Window..." -command {Help window} \ + -underline 3 + .menu.help.m add command -label "On Keys..." -command {Help keys} \ + -underline 3 + .menu.help.m add command -label "On Version..." -command {Help version} \ + -underline 3 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/ruler.tcl ./library/demos.jp/ruler.tcl *** ../../tk8.0.5/library/demos.jp/ruler.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/ruler.tcl Thu Apr 1 00:08:39 1999 *************** *** 0 **** --- 1,175 ---- + # ruler.tcl -- + # + # This demonstration script creates a canvas widget that displays a ruler + # with tab stops that can be set, moved, and deleted. + # + # RCS: @(#) $Id: ruler.tcl,v 1.1 1999/03/31 15:08:39 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # rulerMkTab -- + # This procedure creates a new triangular polygon in a canvas to + # represent a tab stop. + # + # Arguments: + # c - The canvas window. + # x, y - Coordinates at which to create the tab stop. + + proc rulerMkTab {c x y} { + upvar #0 demo_rulerInfo v + $c create polygon $x $y [expr $x+$v(size)] [expr $y+$v(size)] \ + [expr $x-$v(size)] [expr $y+$v(size)] + } + + set w .ruler + global tk_library + catch {destroy $w} + toplevel $w + wm title $w "Ruler Demonstration" + wm iconname $w "ruler" + positionWindow $w + set c $w.c + + label $w.msg -font $font -wraplength 5i -justify left -text [langSel \ + "This canvas widget shows a mock-up of a ruler. You can create tab stops by dragging them out of the well to the right of the ruler. You can also drag existing tab stops. If you drag a tab stop far enough up or down so that it turns dim, it will be deleted when you release the mouse button." \ + "$B$3$N%-%c%s%P%9(B widget $B$O%k!<%i!<$NLO7?$G$9!#%k!<%i!<$N1&$K$"$k$N$O%?%V%9%H%C%W$N0f8M$G!"$3$3$+$i0z$CD%$C$F$/$k$3$H$K$h$C$F%?%V%9%H%C%W$r:n$k$3$H$,$G$-$^$9!#$^$?!"$9$G$K$"$k%?%V%9%H%C%W$rF0$+$9$3$H$b$G$-$^$9!#%?%V%9%H%C%W$r>eJ}$^$?$O2C$($^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + canvas $c -width 14.8c -height 2.5c + pack $w.c -side top -fill x + + set demo_rulerInfo(grid) .25c + set demo_rulerInfo(left) [winfo fpixels $c 1c] + set demo_rulerInfo(right) [winfo fpixels $c 13c] + set demo_rulerInfo(top) [winfo fpixels $c 1c] + set demo_rulerInfo(bottom) [winfo fpixels $c 1.5c] + set demo_rulerInfo(size) [winfo fpixels $c .2c] + set demo_rulerInfo(normalStyle) "-fill black" + if {[winfo depth $c] > 1} { + set demo_rulerInfo(activeStyle) "-fill red -stipple {}" + set demo_rulerInfo(deleteStyle) [list -fill red \ + -stipple @[file join $tk_library demos.jp images gray25.bmp]] + } else { + set demo_rulerInfo(activeStyle) "-fill black -stipple {}" + set demo_rulerInfo(deleteStyle) [list -fill black \ + -stipple @[file join $tk_library demos.jp images gray25.bmp]] + } + + $c create line 1c 0.5c 1c 1c 13c 1c 13c 0.5c -width 1 + for {set i 0} {$i < 12} {incr i} { + set x [expr $i+1] + $c create line ${x}c 1c ${x}c 0.6c -width 1 + $c create line $x.25c 1c $x.25c 0.8c -width 1 + $c create line $x.5c 1c $x.5c 0.7c -width 1 + $c create line $x.75c 1c $x.75c 0.8c -width 1 + $c create text $x.15c .75c -text $i -anchor sw + } + $c addtag well withtag [$c create rect 13.2c 1c 13.8c 0.5c \ + -outline black -fill [lindex [$c config -bg] 4]] + $c addtag well withtag [rulerMkTab $c [winfo pixels $c 13.5c] \ + [winfo pixels $c .65c]] + + $c bind well <1> "rulerNewTab $c %x %y" + $c bind tab <1> "rulerSelectTab $c %x %y" + bind $c "rulerMoveTab $c %x %y" + bind $c "rulerReleaseTab $c" + + # rulerNewTab -- + # Does all the work of creating a tab stop, including creating the + # triangle object and adding tags to it to give it tab behavior. + # + # Arguments: + # c - The canvas window. + # x, y - The coordinates of the tab stop. + + proc rulerNewTab {c x y} { + upvar #0 demo_rulerInfo v + $c addtag active withtag [rulerMkTab $c $x $y] + $c addtag tab withtag active + set v(x) $x + set v(y) $y + rulerMoveTab $c $x $y + } + + # rulerSelectTab -- + # This procedure is invoked when mouse button 1 is pressed over + # a tab. It remembers information about the tab so that it can + # be dragged interactively. + # + # Arguments: + # c - The canvas widget. + # x, y - The coordinates of the mouse (identifies the point by + # which the tab was picked up for dragging). + + proc rulerSelectTab {c x y} { + upvar #0 demo_rulerInfo v + set v(x) [$c canvasx $x $v(grid)] + set v(y) [expr $v(top)+2] + $c addtag active withtag current + eval "$c itemconf active $v(activeStyle)" + $c raise active + } + + # rulerMoveTab -- + # This procedure is invoked during mouse motion events to drag a tab. + # It adjusts the position of the tab, and changes its appearance if + # it is about to be dragged out of the ruler. + # + # Arguments: + # c - The canvas widget. + # x, y - The coordinates of the mouse. + + proc rulerMoveTab {c x y} { + upvar #0 demo_rulerInfo v + if {[$c find withtag active] == ""} { + return + } + set cx [$c canvasx $x $v(grid)] + set cy [$c canvasy $y] + if {$cx < $v(left)} { + set cx $v(left) + } + if {$cx > $v(right)} { + set cx $v(right) + } + if {($cy >= $v(top)) && ($cy <= $v(bottom))} { + set cy [expr $v(top)+2] + eval "$c itemconf active $v(activeStyle)" + } else { + set cy [expr $cy-$v(size)-2] + eval "$c itemconf active $v(deleteStyle)" + } + $c move active [expr $cx-$v(x)] [expr $cy-$v(y)] + set v(x) $cx + set v(y) $cy + } + + # rulerReleaseTab -- + # This procedure is invoked during button release events that end + # a tab drag operation. It deselects the tab and deletes the tab if + # it was dragged out of the ruler. + # + # Arguments: + # c - The canvas widget. + # x, y - The coordinates of the mouse. + + proc rulerReleaseTab c { + upvar #0 demo_rulerInfo v + if {[$c find withtag active] == {}} { + return + } + if {$v(y) != [expr $v(top)+2]} { + $c delete active + } else { + eval "$c itemconf active $v(normalStyle)" + $c dtag active + } + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/sayings.tcl ./library/demos.jp/sayings.tcl *** ../../tk8.0.5/library/demos.jp/sayings.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/sayings.tcl Thu Apr 1 00:08:40 1999 *************** *** 0 **** --- 1,48 ---- + # sayings.tcl -- + # + # This demonstration script creates a listbox that can be scrolled + # both horizontally and vertically. It displays a collection of + # well-known sayings. + # + # RCS: @(#) $Id: sayings.tcl,v 1.1 1999/03/31 15:08:40 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .sayings + catch {destroy $w} + toplevel $w + wm title $w "Listbox Demonstration (well-known sayings)" + wm iconname $w "sayings" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "The listbox below contains a collection of well-known sayings. You can scan the list using either of the scrollbars or by dragging in the listbox window with button 2 pressed." \ + "$B2<$N%j%9%H%\%C%/%9$K$O$$$m$$$m$J3J8@$,F~$C$F$$$^$9!#%j%9%H$r%9%/%m!<%k$5$;$k$N$O%9%/%m!<%k%P!<$G$b$G$-$^$9$7!"%j%9%H%\%C%/%9$NCf$G%^%&%9$N%\%?%s(B2 ($BCf%\%?%s(B) $B$r2!$7$?$^$^%I%i%C%0$7$F$b$G$-$^$9!#(B"] + pack $w.msg -side top + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame -borderwidth 10 + pack $w.frame -side top -expand yes -fill y + + + scrollbar $w.frame.yscroll -command "$w.frame.list yview" + scrollbar $w.frame.xscroll -orient horizontal \ + -command "$w.frame.list xview" + listbox $w.frame.list -width 20 -height 10 -setgrid 1 \ + -yscroll "$w.frame.yscroll set" -xscroll "$w.frame.xscroll set" + + grid $w.frame.list -row 0 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid $w.frame.yscroll -row 0 -column 1 -rowspan 1 -columnspan 1 -sticky news + grid $w.frame.xscroll -row 1 -column 0 -rowspan 1 -columnspan 1 -sticky news + grid rowconfig $w.frame 0 -weight 1 -minsize 0 + grid columnconfig $w.frame 0 -weight 1 -minsize 0 + + + $w.frame.list insert 0 "Waste not, want not" "Early to bed and early to rise makes a man healthy, wealthy, and wise" "Ask not what your country can do for you, ask what you can do for your country" "I shall return" "NOT" "A picture is worth a thousand words" "User interfaces are hard to build" "Thou shalt not steal" "A penny for your thoughts" "Fool me once, shame on you; fool me twice, shame on me" "Every cloud has a silver lining" "Where there's smoke there's fire" "It takes one to know one" "Curiosity killed the cat" "Take this job and shove it" "Up a creek without a paddle" "I'm mad as hell and I'm not going to take it any more" "An apple a day keeps the doctor away" "Don't look a gift horse in the mouth" diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/search.tcl ./library/demos.jp/search.tcl *** ../../tk8.0.5/library/demos.jp/search.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/search.tcl Thu Apr 1 00:08:40 1999 *************** *** 0 **** --- 1,148 ---- + # search.tcl -- + # + # This demonstration script creates a collection of widgets that + # allow you to load a file into a text widget, then perform searches + # on that file. + # + # RCS: @(#) $Id: search.tcl,v 1.1 1999/03/31 15:08:40 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + # textLoadFile -- + # This procedure below loads a file into a text widget, discarding + # the previous contents of the widget. Tags for the old widget are + # not affected, however. + # + # Arguments: + # w - The window into which to load the file. Must be a + # text widget. + # file - The name of the file to load. Must be readable. + + proc textLoadFile {w file} { + set f [open $file] + $w delete 1.0 end + while {![eof $f]} { + $w insert end [read $f 10000] + } + close $f + } + + # textSearch -- + # Search for all instances of a given string in a text widget and + # apply a given tag to each instance found. + # + # Arguments: + # w - The window in which to search. Must be a text widget. + # string - The string to search for. The search is done using + # exact matching only; no special characters. + # tag - Tag to apply to each instance of a matching string. + + proc textSearch {w string tag} { + $w tag remove search 0.0 end + if {$string == ""} { + return + } + set cur 1.0 + while 1 { + set cur [$w search -count length $string $cur end] + if {$cur == ""} { + break + } + $w tag add $tag $cur "$cur + $length char" + set cur [$w index "$cur + $length char"] + } + } + + # textToggle -- + # This procedure is invoked repeatedly to invoke two commands at + # periodic intervals. It normally reschedules itself after each + # execution but if an error occurs (e.g. because the window was + # deleted) then it doesn't reschedule itself. + # + # Arguments: + # cmd1 - Command to execute when procedure is called. + # sleep1 - Ms to sleep after executing cmd1 before executing cmd2. + # cmd2 - Command to execute in the *next* invocation of this + # procedure. + # sleep2 - Ms to sleep after executing cmd2 before executing cmd1 again. + + proc textToggle {cmd1 sleep1 cmd2 sleep2} { + catch { + eval $cmd1 + after $sleep1 [list textToggle $cmd2 $sleep2 $cmd1 $sleep1] + } + } + + set w .search + catch {destroy $w} + toplevel $w + wm title $w "Text Demonstration - Search and Highlight" + wm iconname $w "search" + positionWindow $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.file + label $w.file.label -text [langSel "File name:" "$B%U%!%$%kL>(B:"] -width 13 -anchor w + entry $w.file.entry -width 40 -textvariable fileName + button $w.file.button -text [langSel "Load File" "$B%m!<%I(B"] \ + -command "textLoadFile $w.text \$fileName" + pack $w.file.label $w.file.entry -side left + pack $w.file.button -side left -pady 5 -padx 10 + bind $w.file.entry " + textLoadFile $w.text \$fileName + focus $w.string.entry + " + focus $w.file.entry + + frame $w.string + label $w.string.label -text [langSel "Search string:" "$B8!:wJ8;zNs(B:"] -width 13 -anchor w + entry $w.string.entry -width 40 -textvariable searchString + button $w.string.button -text [langSel "Highlight" "$BH?E>(B"] \ + -command "textSearch $w.text \$searchString search" + pack $w.string.label $w.string.entry -side left + pack $w.string.button -side left -pady 5 -padx 10 + bind $w.string.entry "textSearch $w.text \$searchString search" + + text $w.text -yscrollcommand "$w.scroll set" -setgrid true + scrollbar $w.scroll -command "$w.text yview" + pack $w.file $w.string -side top -fill x + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + + # Set up display styles for text highlighting. + + if {[winfo depth $w] > 1} { + textToggle "$w.text tag configure search -background \ + #ce5555 -foreground white" 800 "$w.text tag configure \ + search -background {} -foreground {}" 200 + } else { + textToggle "$w.text tag configure search -background \ + black -foreground white" 800 "$w.text tag configure \ + search -background {} -foreground {}" 200 + } + $w.text insert 1.0 [langSel \ + {This window demonstrates how to use the tagging facilities in text + widgets to implement a searching mechanism. First, type a file name + in the top entry, then type or click on "Load File". Then + type a string in the lower entry and type or click on + "Load File". This will cause all of the instances of the string to + be tagged with the tag "search", and it will arrange for the tag's + display attributes to change to make all of the strings blink.} \ + {$B$3$N%&%#%s%I%&$O8!:w5!9=$re$N%(%s%H%j$K%U%!%$%kL>$rF~(B + $B$l!"(B<$B%j%?!<%s(B> $B$r2!$9$+!V%m!<%I!W%\%?%s$r2!$7$F$/$@$5$$!# $B$r2!$9$+!VH?E>!W%\%?%s$r2!$7$F$/(B + $B$@$5$$!#$9$k$H%U%!%$%kCf$N!"8!:wJ8;zNs$H0lCW$9$kItJ,$KA4$F(B "search" + $B$H$$$&%?%0$,$D$1$i$l!"%?%0$NI=<(B0@-$H$7$F$=$NJ8;zNs$,E@LG$9$k$h$&$K(B + $B@_Dj$5$l$^$9!#(B}] + $w.text mark set insert 0.0 + + set fileName "" + set searchString "" diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/square ./library/demos.jp/square *** ../../tk8.0.5/library/demos.jp/square Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/square Thu Apr 1 00:08:40 1999 *************** *** 0 **** --- 1,55 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # square -- + # This script generates a demo application containing only a "square" + # widget. It's only usable in the "tktest" application or if Tk has + # been compiled with tkSquare.c. This demo arranges the following + # bindings for the widget: + # + # Button-1 press/drag: moves square to mouse + # "a": toggle size animation on/off + # + # RCS: @(#) $Id: square,v 1.1 1999/03/31 15:08:40 m-hirano Exp $ + + square .s + pack .s -expand yes -fill both + wm minsize . 1 1 + + bind .s <1> {center %x %y} + bind .s {center %x %y} + bind .s a animate + focus .s + + # The procedure below centers the square on a given position. + + proc center {x y} { + set a [.s size] + .s position [expr $x-($a/2)] [expr $y-($a/2)] + } + + # The procedures below provide a simple form of animation where + # the box changes size in a pulsing pattern: larger, smaller, larger, + # and so on. + + set inc 0 + proc animate {} { + global inc + if {$inc == 0} { + set inc 3 + timer + } else { + set inc 0 + } + } + + proc timer {} { + global inc + set s [.s size] + if {$inc == 0} return + if {$s >= 40} {set inc -3} + if {$s <= 10} {set inc 3} + .s size [expr {$s+$inc}] + after 30 timer + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/states.tcl ./library/demos.jp/states.tcl *** ../../tk8.0.5/library/demos.jp/states.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/states.tcl Thu Apr 1 00:08:41 1999 *************** *** 0 **** --- 1,61 ---- + # states.tcl -- + # + # This demonstration script creates a listbox widget that displays + # the names of the 50 states in the United States of America. + # + # RCS: @(#) $Id: states.tcl,v 1.1 1999/03/31 15:08:41 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .states + catch {destroy $w} + toplevel $w + wm title $w "Listbox Demonstration (50 states)" + wm iconname $w "states" + positionWindow $w + + label $w.msg -font $font -wraplength 4i -justify left -text [langSel \ + "A listbox containing the 50 states is displayed below, along with a scrollbar. You can scan the list either using the scrollbar or by scanning. To scan, press button 2 in the widget and drag up or down." \ + "$B2<$K$"$k$N$OETF;I\8)L>$,F~$C$?%9%/%m!<%k%P!H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame -borderwidth .5c + pack $w.frame -side top -expand yes -fill y + + scrollbar $w.frame.scroll -command "$w.frame.list yview" + listbox $w.frame.list -yscroll "$w.frame.scroll set" -setgrid 1 -height 12 + pack $w.frame.scroll -side right -fill y + pack $w.frame.list -side left -expand 1 -fill both + + langSwitch { + $w.frame.list insert 0 Alabama Alaska Arizona Arkansas California \ + Colorado Connecticut Delaware Florida Georgia Hawaii Idaho Illinois \ + Indiana Iowa Kansas Kentucky Louisiana Maine Maryland \ + Massachusetts Michigan Minnesota Mississippi Missouri \ + Montana Nebraska Nevada "New Hampshire" "New Jersey" "New Mexico" \ + "New York" "North Carolina" "North Dakota" \ + Ohio Oklahoma Oregon Pennsylvania "Rhode Island" \ + "South Carolina" "South Dakota" \ + Tennessee Texas Utah Vermont Virginia Washington \ + "West Virginia" Wisconsin Wyoming + } { + $w.frame.list insert 0 \ + $B0&CN(B $B@D?9(B $B=)ED(B $B@P@n(B $B0q>k(B \ + $B4dk(B $B5\:j(B $B;37A(B $B;38}(B \ + $B;3M|(B $BOB2N;3(B + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/style.tcl ./library/demos.jp/style.tcl *** ../../tk8.0.5/library/demos.jp/style.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/style.tcl Thu Apr 1 00:08:41 1999 *************** *** 0 **** --- 1,245 ---- + # style.tcl -- + # + # This demonstration script creates a text widget that illustrates the + # various display styles that may be set for tags. + # + # RCS: @(#) $Id: style.tcl,v 1.1 1999/03/31 15:08:41 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .style + catch {destroy $w} + toplevel $w + wm title $w "Text Demonstration - Display Styles" + wm iconname $w "style" + positionWindow $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + text $w.text -yscrollcommand "$w.scroll set" -setgrid true \ + -width 70 -height 32 -wrap word + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + + # Set up display styles + + $w.text tag configure bold -font {Courier12bolditalic} + $w.text tag configure big -font {Courier14bold} + $w.text tag configure verybig -font {Helvetica24bold} + $w.text tag configure small -font {Helvetica10} + if {[winfo depth $w] > 1} { + $w.text tag configure color1 -background #a0b7ce + $w.text tag configure color2 -foreground red + $w.text tag configure raised -relief raised -borderwidth 1 + $w.text tag configure sunken -relief sunken -borderwidth 1 + } else { + $w.text tag configure color1 -background black -foreground white + $w.text tag configure color2 -background black -foreground white + $w.text tag configure raised -background white -relief raised \ + -borderwidth 1 + $w.text tag configure sunken -background white -relief sunken \ + -borderwidth 1 + } + $w.text tag configure bgstipple -background black -borderwidth 0 \ + -bgstipple gray12 + $w.text tag configure fgstipple -fgstipple gray50 + $w.text tag configure underline -underline on + $w.text tag configure overstrike -overstrike on + $w.text tag configure right -justify right + $w.text tag configure center -justify center + $w.text tag configure super -offset 4p -font {Courier 10} + $w.text tag configure sub -offset -2p -font {Courier 10} + $w.text tag configure margins -lmargin1 12m -lmargin2 6m -rmargin 10m + $w.text tag configure spacing -spacing1 10p -spacing2 2p \ + -lmargin1 12m -lmargin2 6m -rmargin 10m + + langSwitch { + $w.text insert end {Text widgets like this one allow you to display information in a + variety of styles. Display styles are controlled using a mechanism + called } + $w.text insert end tags bold + $w.text insert end {. Tags are just textual names that you can apply to one + or more ranges of characters within a text widget. You can configure + tags with various display styles. If you do this, then the tagged + characters will be displayed with the styles you chose. The + available display styles are: + } + $w.text insert end "\n1. Font." big + $w.text insert end " You can choose any X font, " + $w.text insert end large verybig + $w.text insert end " or " + $w.text insert end "small.\n" + $w.text insert end "\n2. Color." big + $w.text insert end " You can change either the " + $w.text insert end background color1 + $w.text insert end " or " + $w.text insert end foreground color2 + $w.text insert end "\ncolor, or " + $w.text insert end both {color1 color2} + $w.text insert end ".\n" + $w.text insert end "\n3. Stippling." big + $w.text insert end " You can cause either the " + $w.text insert end background bgstipple + $w.text insert end " or " + $w.text insert end foreground fgstipple + $w.text insert end { + information to be drawn with a stipple fill instead of a solid fill. + } + $w.text insert end "\n4. Underlining." big + $w.text insert end " You can " + $w.text insert end underline underline + $w.text insert end " ranges of text.\n" + $w.text insert end "\n5. Overstrikes." big + $w.text insert end " You can " + $w.text insert end "draw lines through" overstrike + $w.text insert end " ranges of text.\n" + $w.text insert end "\n6. 3-D effects." big + $w.text insert end { You can arrange for the background to be drawn + with a border that makes characters appear either } + $w.text insert end raised raised + $w.text insert end " or " + $w.text insert end sunken sunken + $w.text insert end ".\n" + $w.text insert end "\n7. Justification." big + $w.text insert end " You can arrange for lines to be displayed\n" + $w.text insert end "left-justified,\n" + $w.text insert end "right-justified, or\n" right + $w.text insert end "centered.\n" center + $w.text insert end "\n8. Superscripts and subscripts." big + $w.text insert end " You can control the vertical\n" + $w.text insert end "position of text to generate superscript effects like 10" + $w.text insert end "n" super + $w.text insert end " or\nsubscript effects like X" + $w.text insert end "i" sub + $w.text insert end ".\n" + $w.text insert end "\n9. Margins." big + $w.text insert end " You can control the amount of extra space left" + $w.text insert end " on\neach side of the text:\n" + $w.text insert end "This paragraph is an example of the use of " margins + $w.text insert end "margins. It consists of a single line of text " margins + $w.text insert end "that wraps around on the screen. There are two " margins + $w.text insert end "separate left margin values, one for the first " margins + $w.text insert end "display line associated with the text line, " margins + $w.text insert end "and one for the subsequent display lines, which " margins + $w.text insert end "occur because of wrapping. There is also a " margins + $w.text insert end "separate specification for the right margin, " margins + $w.text insert end "which is used to choose wrap points for lines.\n" margins + $w.text insert end "\n10. Spacing." big + $w.text insert end " You can control the spacing of lines with three\n" + $w.text insert end "separate parameters. \"Spacing1\" tells how much " + $w.text insert end "extra space to leave\nabove a line, \"spacing3\" " + $w.text insert end "tells how much space to leave below a line,\nand " + $w.text insert end "if a text line wraps, \"spacing2\" tells how much " + $w.text insert end "space to leave\nbetween the display lines that " + $w.text insert end "make up the text line.\n" + $w.text insert end "These indented paragraphs illustrate how spacing " spacing + $w.text insert end "can be used. Each paragraph is actually a " spacing + $w.text insert end "single line in the text widget, which is " spacing + $w.text insert end "word-wrapped by the widget.\n" spacing + $w.text insert end "Spacing1 is set to 10 points for this text, " spacing + $w.text insert end "which results in relatively large gaps between " spacing + $w.text insert end "the paragraphs. Spacing2 is set to 2 points, " spacing + $w.text insert end "which results in just a bit of extra space " spacing + $w.text insert end "within a pararaph. Spacing3 isn't used " spacing + $w.text insert end "in this example.\n" spacing + $w.text insert end "To see where the space is, select ranges of " spacing + $w.text insert end "text within these paragraphs. The selection " spacing + $w.text insert end "highlight will cover the extra space." spacing + } { + $w.text insert end \ + {$B$3$N$h$&$K%F%-%9%H(B widget $B$O>pJs$rMM!9$J%9%?%$%k$GI=<($9$k$3$H(B + $B$,$G$-$^$9!#I=<(%9%?%$%k$O(B} + $w.text insert end $B%?%0(B bold + $w.text insert end {$B$H$$$&%a%+%K%:%`$G%3%s%H%m!<%k$5$l$^$9!#(B + $B%?%0$H$O%F%-%9%H(B widget $BFb$N$"$kJ8;z(B ($B$NHO0O(B)$B$KBP$7$FE,MQ$G$-$k(B + $BC1$J$kL>A0$N$3$H$G$9!#%?%0$OMM!9$JI=<(%9%?%$%k$K@_Dj$G$-$^$9!#(B + $B@_Dj$9$k$H!"$=$N%?%0$N$D$$$?J8;z$O;XDj$7$?%9%?%$%k$GI=<($5$l$k(B + $B$h$&$K$J$j$^$9!#;HMQ$G$-$kI=<(%9%?%$%k$O.$5$$(B small + $w.text insert end "$B$H$+!#(B\n" + $w.text insert end "\n2. $B?'(B" big + $w.text insert end " " + $w.text insert end $BGX7J?'(B color1 + $w.text insert end "$B$b(B" + $w.text insert end $BA07J?'(B color2 + $w.text insert end "$B$b(B" + $w.text insert end $BN>J}(B {color1 color2} + $w.text insert end "$B$H$bJQ$($k$3$H$,$G$-$^$9!#(B\n" + $w.text insert end "\n3. $BLV$+$1(B" big + $w.text insert end " $B$3$N$h$&$KIA2h$N:]$K(B" + $w.text insert end $BGX7J(B bgstipple + $w.text insert end "$B$b(B" + $w.text insert end $BJ8;z(B fgstipple + $w.text insert end { + $B$bC1$J$kEI$j$D$V$7$G$J$/!"LV$+$1$r;H$&$3$H$,$G$-$^$9!#(B + } + $w.text insert end "\n4. $B2<@~(B" big + $w.text insert end " $B$3$N$h$&$K(B" + $w.text insert end "$BJ8;z$K2<@~$r0z$/(B" underline + $w.text insert end "$B$3$H$,$G$-$^$9!#(B\n" + $w.text insert end "\n5. $BBG$A>C$7@~(B" big + $w.text insert end " $B$3$N$h$&$K(B" + $w.text insert end "$BJ8;z$K=E$M$F@~$r0z$/(B" overstrike + $w.text insert end "$B$3$H$,$G$-$^$9!#(B\n" + $w.text insert end "\n6. 3D $B8z2L(B" big + $w.text insert end " $BGX7J$KOH$r$D$1$F!"J8;z$r(B" + $w.text insert end "$BHt$S=P$9(B" raised + $w.text insert end "$B$h$&$K$7$?$j(B" + $w.text insert end "$BD@$`(B" sunken + $w.text insert end "$B$h$&(B\n$B$K$G$-$^$9!#(B\n" + $w.text insert end "\n7. $B9TB7$((B" big + $w.text insert end " $B$3$N$h$&$K9T$r(B\n" + $w.text insert end "$B:8$KB7$($?$j(B\n" + $w.text insert end "$B1&$KB7$($?$j(B\n" right + $w.text insert end "$B??Cf$KB7$($?$j$G$-$^$9!#(B\n" center + $w.text insert end "\n8. $B8*IU$-J8;z$HE:;z(B" big + $w.text insert end " 10" + $w.text insert end "n" super + $w.text insert end "$B$N$h$&$K8*IU$-J8;z$N8z2L$d!"(B\nX" + $w.text insert end "i" sub + $w.text insert end "$B$N$h$&$KE:;z$N8z2L$r=P$9$3$H$,$G$-$^$9!#(B\n" + $w.text insert end "\n9. $B%^!<%8%s(B" big + $w.text insert end " $B%F%-%9%H$N:8B&$KM>J,$J6uGr$r(B" + $w.text insert end "$BCV$/$3$H$,$G$-$^$9(B:\n" + $w.text insert end "$B$3$NCJMn$O%^!<%8%s$N;HMQNc$G$9!#%9%/%j!<%s(B" margins + $w.text insert end "$B>e$G@^$jJV$5$l$FI=<($5$l$F$$$k(B1$B9T$N%F%-%9%H$G$9!#(B" margins + $w.text insert end "$B:8B&$K$O(B2$Be$K$I$N$/$i$$$N(B" + $w.text insert end "$B6u4V$rCV$/$+!"(B\n\"spacing3\"$B$G9T$N2<$K$I$N$/$i$$$N(B" + $w.text insert end "$B6u4V$rCV$/$+!"9T$,@^$jJV$5$l$F(B\n$B$$$k$J$i$P!"(B" + $w.text insert end "\"spacing2\"$B$G!"%F%-%9%H9T$r@8@.$7$F$$$k9T$N4V$K(B\n" + $w.text insert end "$B$I$N$/$i$$$N6u4V$rCV$/$+$r<($7$^$9!#(B\n" + $w.text insert end "$B$3$l$i$N%$%s%G%s%H$5$l$?CJMn$O$I$N$h$&$K(B" spacing + $w.text insert end "$B%9%Z!<%7%s%0$,$,9T$o$l$k$N$+$r<($7$^$9!#(B" spacing + $w.text insert end "$B3FCJMn$Ov$^$l$F$$$^$9!#(B\n" spacing + $w.text insert end "Spacing1$B$O$3$N%F%-%9%H$G$O(B10point$B$K(B" spacing + $w.text insert end "$B@_Dj$5$l$F$$$^$9!#(B" spacing + $w.text insert end "$B$3$l$K$h$j!"CJMn$N4V$KBg$-$J4V3V$,(B" spacing + $w.text insert end "$BB8:_$7$F$$$^$9!#(B" spacing + $w.text insert end "Spacing2$B$O(B2point$B$K@_Dj$5$l$F$$$^$9!#(B" spacing + $w.text insert end "$B$3$l$GCJMn$NCf$K$[$s$N>/$74V3V$,B8:_$7$F$$$^$9!#(B" spacing + $w.text insert end "Spacing3$B$O$3$NNc$G$O;HMQ$5$l$F$$$^$;$s!#(B\n" spacing + $w.text insert end "$B4V3V$,$I$3$K$"$k$+$r8+$?$1$l$P!"$3$l$i$NCJMn$N(B" spacing + $w.text insert end "$B$J$+$G%F%-%9%H$rA*Br$7$F$/$@$5$$!#A*Br$N(B" spacing + $w.text insert end "$BH?E>$7$?ItJ,$K$OM>J,$K$H$i$l$?4V3V$,(B" spacing + $w.text insert end "$B4^$^$l$F$$$^$9!#(B\n" spacing + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/tclIndex ./library/demos.jp/tclIndex *** ../../tk8.0.5/library/demos.jp/tclIndex Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/tclIndex Thu Apr 1 00:08:42 1999 *************** *** 0 **** --- 1,67 ---- + # Tcl autoload index file, version 2.0 + # This file is generated by the "auto_mkindex" command + # and sourced to set up indexing information for one or + # more commands. Typically each line is a command that + # sets an element in the auto_index array, where the + # element name is the name of a command and the value is + # a script that loads the command. + + set auto_index(arrowSetup) [list source [file join $dir arrow.tcl]] + set auto_index(arrowMove1) [list source [file join $dir arrow.tcl]] + set auto_index(arrowMove2) [list source [file join $dir arrow.tcl]] + set auto_index(arrowMove3) [list source [file join $dir arrow.tcl]] + set auto_index(textLoadFile) [list source [file join $dir search.tcl]] + set auto_index(textSearch) [list source [file join $dir search.tcl]] + set auto_index(textToggle) [list source [file join $dir search.tcl]] + set auto_index(itemEnter) [list source [file join $dir items.tcl]] + set auto_index(itemLeave) [list source [file join $dir items.tcl]] + set auto_index(itemMark) [list source [file join $dir items.tcl]] + set auto_index(itemStroke) [list source [file join $dir items.tcl]] + set auto_index(itemsUnderArea) [list source [file join $dir items.tcl]] + set auto_index(itemStartDrag) [list source [file join $dir items.tcl]] + set auto_index(itemDrag) [list source [file join $dir items.tcl]] + set auto_index(butPress) [list source [file join $dir items.tcl]] + set auto_index(loadDir) [list source [file join $dir image2.tcl]] + set auto_index(loadImage) [list source [file join $dir image2.tcl]] + set auto_index(rulerMkTab) [list source [file join $dir ruler.tcl]] + set auto_index(rulerNewTab) [list source [file join $dir ruler.tcl]] + set auto_index(rulerSelectTab) [list source [file join $dir ruler.tcl]] + set auto_index(rulerMoveTab) [list source [file join $dir ruler.tcl]] + set auto_index(rulerReleaseTab) [list source [file join $dir ruler.tcl]] + set auto_index(mkTextConfig) [list source [file join $dir ctext.tcl]] + set auto_index(textEnter) [list source [file join $dir ctext.tcl]] + set auto_index(textInsert) [list source [file join $dir ctext.tcl]] + set auto_index(textPaste) [list source [file join $dir ctext.tcl]] + set auto_index(textB1Press) [list source [file join $dir ctext.tcl]] + set auto_index(textB1Move) [list source [file join $dir ctext.tcl]] + set auto_index(textBs) [list source [file join $dir ctext.tcl]] + set auto_index(textDel) [list source [file join $dir ctext.tcl]] + set auto_index(bitmapRow) [list source [file join $dir bitmap.tcl]] + set auto_index(scrollEnter) [list source [file join $dir cscroll.tcl]] + set auto_index(scrollLeave) [list source [file join $dir cscroll.tcl]] + set auto_index(scrollButton) [list source [file join $dir cscroll.tcl]] + set auto_index(textWindOn) [list source [file join $dir twind.tcl]] + set auto_index(textWindOff) [list source [file join $dir twind.tcl]] + set auto_index(textWindPlot) [list source [file join $dir twind.tcl]] + set auto_index(embPlotDown) [list source [file join $dir twind.tcl]] + set auto_index(embPlotMove) [list source [file join $dir twind.tcl]] + set auto_index(textWindDel) [list source [file join $dir twind.tcl]] + set auto_index(embDefBg) [list source [file join $dir twind.tcl]] + set auto_index(floorDisplay) [list source [file join $dir floor.tcl]] + set auto_index(newRoom) [list source [file join $dir floor.tcl]] + set auto_index(roomChanged) [list source [file join $dir floor.tcl]] + set auto_index(bg1) [list source [file join $dir floor.tcl]] + set auto_index(bg2) [list source [file join $dir floor.tcl]] + set auto_index(bg3) [list source [file join $dir floor.tcl]] + set auto_index(fg1) [list source [file join $dir floor.tcl]] + set auto_index(fg2) [list source [file join $dir floor.tcl]] + set auto_index(fg3) [list source [file join $dir floor.tcl]] + set auto_index(setWidth) [list source [file join $dir hscale.tcl]] + set auto_index(plotDown) [list source [file join $dir plot.tcl]] + set auto_index(plotMove) [list source [file join $dir plot.tcl]] + set auto_index(puzzleSwitch) [list source [file join $dir puzzle.tcl]] + set auto_index(setHeight) [list source [file join $dir vscale.tcl]] + set auto_index(showMessageBox) [list source [file join $dir msgbox.tcl]] + set auto_index(setColor) [list source [file join $dir clrpick.tcl]] + set auto_index(setColor_helper) [list source [file join $dir clrpick.tcl]] + set auto_index(fileDialog) [list source [file join $dir filebox.tcl]] diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/tcolor ./library/demos.jp/tcolor *** ../../tk8.0.5/library/demos.jp/tcolor Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/tcolor Thu Apr 1 00:08:42 1999 *************** *** 0 **** --- 1,358 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # tcolor -- + # This script implements a simple color editor, where you can + # create colors using either the RGB, HSB, or CYM color spaces + # and apply the color to existing applications. + # + # RCS: @(#) $Id: tcolor,v 1.1 1999/03/31 15:08:42 m-hirano Exp $ + + wm title . "Color Editor" + + # Global variables that control the program: + # + # colorSpace - Color space currently being used for + # editing. Must be "rgb", "cmy", or "hsb". + # label1, label2, label3 - Labels for the scales. + # red, green, blue - Current color intensities in decimal + # on a scale of 0-65535. + # color - A string giving the current color value + # in the proper form for x: + # #RRRRGGGGBBBB + # updating - Non-zero means that we're in the middle of + # updating the scales to load a new color,so + # information shouldn't be propagating back + # from the scales to other elements of the + # program: this would make an infinite loop. + # command - Holds the command that has been typed + # into the "Command" entry. + # autoUpdate - 1 means execute the update command + # automatically whenever the color changes. + # name - Name for new color, typed into entry. + + set colorSpace hsb + set red 65535 + set green 0 + set blue 0 + set color #ffff00000000 + set updating 0 + set autoUpdate 1 + set name "" + + # Create the menu bar at the top of the window. + + frame .menu -relief raised -borderwidth 2 + pack .menu -side top -fill x + menubutton .menu.file -text File -menu .menu.file.m -underline 0 + menu .menu.file.m + .menu.file.m add radio -label "RGB color space" -variable colorSpace \ + -value rgb -underline 0 -command {changeColorSpace rgb} + .menu.file.m add radio -label "CMY color space" -variable colorSpace \ + -value cmy -underline 0 -command {changeColorSpace cmy} + .menu.file.m add radio -label "HSB color space" -variable colorSpace \ + -value hsb -underline 0 -command {changeColorSpace hsb} + .menu.file.m add separator + .menu.file.m add radio -label "Automatic updates" -variable autoUpdate \ + -value 1 -underline 0 + .menu.file.m add radio -label "Manual updates" -variable autoUpdate \ + -value 0 -underline 0 + .menu.file.m add separator + .menu.file.m add command -label "Exit program" -underline 0 \ + -command "destroy ." + pack .menu.file -side left + + # Create the command entry window at the bottom of the window, along + # with the update button. + + frame .bot -relief raised -borderwidth 2 + pack .bot -side bottom -fill x + label .commandLabel -text "Command:" + entry .command -relief sunken -borderwidth 2 -textvariable command \ + -font {Courier 12} + button .update -text Update -command doUpdate + pack .commandLabel -in .bot -side left + pack .update -in .bot -side right -pady .1c -padx .25c + pack .command -in .bot -expand yes -fill x -ipadx 0.25c + + # Create the listbox that holds all of the color names in rgb.txt, + # if an rgb.txt file can be found. + + frame .middle -relief raised -borderwidth 2 + pack .middle -side top -fill both + foreach i {/usr/local/lib/X11/rgb.txt /usr/lib/X11/rgb.txt + /X11/R5/lib/X11/rgb.txt /X11/R4/lib/rgb/rgb.txt + /usr/openwin/lib/X11/rgb.txt} { + if ![file readable $i] { + continue; + } + set f [open $i] + frame .middle.left + pack .middle.left -side left -padx .25c -pady .25c + listbox .names -width 20 -height 12 -yscrollcommand ".scroll set" \ + -relief sunken -borderwidth 2 -exportselection false + bind .names { + tc_loadNamedColor [.names get [.names curselection]] + } + scrollbar .scroll -orient vertical -command ".names yview" \ + -relief sunken -borderwidth 2 + pack .names -in .middle.left -side left + pack .scroll -in .middle.left -side right -fill y + while {[gets $f line] >= 0} { + if {[llength $line] == 4} { + .names insert end [lindex $line 3] + } + } + close $f + break + } + + # Create the three scales for editing the color, and the entry for + # typing in a color value. + + frame .middle.middle + pack .middle.middle -side left -expand yes -fill y + frame .middle.middle.1 + frame .middle.middle.2 + frame .middle.middle.3 + frame .middle.middle.4 + pack .middle.middle.1 .middle.middle.2 .middle.middle.3 -side top -expand yes + pack .middle.middle.4 -side top -expand yes -fill x + foreach i {1 2 3} { + label .label$i -textvariable label$i + scale .scale$i -from 0 -to 1000 -length 6c -orient horizontal \ + -command tc_scaleChanged + pack .scale$i .label$i -in .middle.middle.$i -side top -anchor w + } + label .nameLabel -text "Name:" + entry .name -relief sunken -borderwidth 2 -textvariable name -width 10 \ + -font {Courier 12} + pack .nameLabel -in .middle.middle.4 -side left + pack .name -in .middle.middle.4 -side right -expand 1 -fill x + bind .name {tc_loadNamedColor $name} + + # Create the color display swatch on the right side of the window. + + frame .middle.right + pack .middle.right -side left -pady .25c -padx .25c -anchor s + frame .swatch -width 2c -height 5c -background $color + label .value -textvariable color -width 13 -font {Courier 12} + pack .swatch -in .middle.right -side top -expand yes -fill both + pack .value -in .middle.right -side bottom -pady .25c + + # The procedure below is invoked when one of the scales is adjusted. + # It propagates color information from the current scale readings + # to everywhere else that it is used. + + proc tc_scaleChanged args { + global red green blue colorSpace color updating autoUpdate + if $updating { + return + } + if {$colorSpace == "rgb"} { + set red [format %.0f [expr [.scale1 get]*65.535]] + set green [format %.0f [expr [.scale2 get]*65.535]] + set blue [format %.0f [expr [.scale3 get]*65.535]] + } else { + if {$colorSpace == "cmy"} { + set red [format %.0f [expr {65535 - [.scale1 get]*65.535}]] + set green [format %.0f [expr {65535 - [.scale2 get]*65.535}]] + set blue [format %.0f [expr {65535 - [.scale3 get]*65.535}]] + } else { + set list [hsbToRgb [expr {[.scale1 get]/1000.0}] \ + [expr {[.scale2 get]/1000.0}] \ + [expr {[.scale3 get]/1000.0}]] + set red [lindex $list 0] + set green [lindex $list 1] + set blue [lindex $list 2] + } + } + set color [format "#%04x%04x%04x" $red $green $blue] + .swatch config -bg $color + if $autoUpdate doUpdate + update idletasks + } + + # The procedure below is invoked to update the scales from the + # current red, green, and blue intensities. It's invoked after + # a change in the color space and after a named color value has + # been loaded. + + proc tc_setScales {} { + global red green blue colorSpace updating + set updating 1 + if {$colorSpace == "rgb"} { + .scale1 set [format %.0f [expr $red/65.535]] + .scale2 set [format %.0f [expr $green/65.535]] + .scale3 set [format %.0f [expr $blue/65.535]] + } else { + if {$colorSpace == "cmy"} { + .scale1 set [format %.0f [expr (65535-$red)/65.535]] + .scale2 set [format %.0f [expr (65535-$green)/65.535]] + .scale3 set [format %.0f [expr (65535-$blue)/65.535]] + } else { + set list [rgbToHsv $red $green $blue] + .scale1 set [format %.0f [expr {[lindex $list 0] * 1000.0}]] + .scale2 set [format %.0f [expr {[lindex $list 1] * 1000.0}]] + .scale3 set [format %.0f [expr {[lindex $list 2] * 1000.0}]] + } + } + set updating 0 + } + + # The procedure below is invoked when a named color has been + # selected from the listbox or typed into the entry. It loads + # the color into the editor. + + proc tc_loadNamedColor name { + global red green blue color autoUpdate + + if {[string index $name 0] != "#"} { + set list [winfo rgb .swatch $name] + set red [lindex $list 0] + set green [lindex $list 1] + set blue [lindex $list 2] + } else { + case [string length $name] { + 4 {set format "#%1x%1x%1x"; set shift 12} + 7 {set format "#%2x%2x%2x"; set shift 8} + 10 {set format "#%3x%3x%3x"; set shift 4} + 13 {set format "#%4x%4x%4x"; set shift 0} + default {error "syntax error in color name \"$name\""} + } + if {[scan $name $format red green blue] != 3} { + error "syntax error in color name \"$name\"" + } + set red [expr $red<<$shift] + set green [expr $green<<$shift] + set blue [expr $blue<<$shift] + } + tc_setScales + set color [format "#%04x%04x%04x" $red $green $blue] + .swatch config -bg $color + if $autoUpdate doUpdate + } + + # The procedure below is invoked when a new color space is selected. + # It changes the labels on the scales and re-loads the scales with + # the appropriate values for the current color in the new color space + + proc changeColorSpace space { + global label1 label2 label3 + if {$space == "rgb"} { + set label1 Red + set label2 Green + set label3 Blue + tc_setScales + return + } + if {$space == "cmy"} { + set label1 Cyan + set label2 Magenta + set label3 Yellow + tc_setScales + return + } + if {$space == "hsb"} { + set label1 Hue + set label2 Saturation + set label3 Brightness + tc_setScales + return + } + } + + # The procedure below converts an RGB value to HSB. It takes red, green, + # and blue components (0-65535) as arguments, and returns a list containing + # HSB components (floating-point, 0-1) as result. The code here is a copy + # of the code on page 615 of "Fundamentals of Interactive Computer Graphics" + # by Foley and Van Dam. + + proc rgbToHsv {red green blue} { + if {$red > $green} { + set max $red.0 + set min $green.0 + } else { + set max $green.0 + set min $red.0 + } + if {$blue > $max} { + set max $blue.0 + } else { + if {$blue < $min} { + set min $blue.0 + } + } + set range [expr $max-$min] + if {$max == 0} { + set sat 0 + } else { + set sat [expr {($max-$min)/$max}] + } + if {$sat == 0} { + set hue 0 + } else { + set rc [expr {($max - $red)/$range}] + set gc [expr {($max - $green)/$range}] + set bc [expr {($max - $blue)/$range}] + if {$red == $max} { + set hue [expr {.166667*($bc - $gc)}] + } else { + if {$green == $max} { + set hue [expr {.166667*(2 + $rc - $bc)}] + } else { + set hue [expr {.166667*(4 + $gc - $rc)}] + } + } + if {$hue < 0.0} { + set hue [expr $hue + 1.0] + } + } + return [list $hue $sat [expr {$max/65535}]] + } + + # The procedure below converts an HSB value to RGB. It takes hue, saturation, + # and value components (floating-point, 0-1.0) as arguments, and returns a + # list containing RGB components (integers, 0-65535) as result. The code + # here is a copy of the code on page 616 of "Fundamentals of Interactive + # Computer Graphics" by Foley and Van Dam. + + proc hsbToRgb {hue sat value} { + set v [format %.0f [expr 65535.0*$value]] + if {$sat == 0} { + return "$v $v $v" + } else { + set hue [expr $hue*6.0] + if {$hue >= 6.0} { + set hue 0.0 + } + scan $hue. %d i + set f [expr $hue-$i] + set p [format %.0f [expr {65535.0*$value*(1 - $sat)}]] + set q [format %.0f [expr {65535.0*$value*(1 - ($sat*$f))}]] + set t [format %.0f [expr {65535.0*$value*(1 - ($sat*(1 - $f)))}]] + case $i \ + 0 {return "$v $t $p"} \ + 1 {return "$q $v $p"} \ + 2 {return "$p $v $t"} \ + 3 {return "$p $q $v"} \ + 4 {return "$t $p $v"} \ + 5 {return "$v $p $q"} + error "i value $i is out of range" + } + } + + # The procedure below is invoked when the "Update" button is pressed, + # and whenever the color changes if update mode is enabled. It + # propagates color information as determined by the command in the + # Command entry. + + proc doUpdate {} { + global color command + set newCmd $command + regsub -all %% $command $color newCmd + eval $newCmd + } + + changeColorSpace hsb diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/text.tcl ./library/demos.jp/text.tcl *** ../../tk8.0.5/library/demos.jp/text.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/text.tcl Thu Apr 1 00:08:43 1999 *************** *** 0 **** --- 1,116 ---- + # text.tcl -- + # + # This demonstration script creates a text widget that describes + # the basic editing functions. + # + # RCS: @(#) $Id: text.tcl,v 1.1 1999/03/31 15:08:43 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .text + catch {destroy $w} + toplevel $w + wm title $w "Text Demonstration - Basic Facilities" + wm iconname $w "text" + positionWindow $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + text $w.text -relief sunken -bd 2 -yscrollcommand "$w.scroll set" -setgrid 1 \ + -height 30 + scrollbar $w.scroll -command "$w.text yview" + pack $w.scroll -side right -fill y + pack $w.text -expand yes -fill both + $w.text insert 0.0 [langSel \ + {This window is a text widget. It displays one or more lines of text + and allows you to edit the text. Here is a summary of the things you + can do to a text widget: + + 1. Scrolling. Use the scrollbar to adjust the view in the text window. + + 2. Scanning. Press mouse button 2 in the text window and drag up or down. + This will drag the text at high speed to allow you to scan its contents. + + 3. Insert text. Press mouse button 1 to set the insertion cursor, then + type text. What you type will be added to the widget. + + 4. Select. Press mouse button 1 and drag to select a range of characters. + Once you've released the button, you can adjust the selection by pressing + button 1 with the shift key down. This will reset the end of the + selection nearest the mouse cursor and you can drag that end of the + selection by dragging the mouse before releasing the mouse button. + You can double-click to select whole words or triple-click to select + whole lines. + + 5. Delete and replace. To delete text, select the characters you'd like + to delete and type Backspace or Delete. Alternatively, you can type new + text, in which case it will replace the selected text. + + 6. Copy the selection. To copy the selection into this window, select + what you want to copy (either here or in another application), then + click button 2 to copy the selection to the point of the mouse cursor. + + 7. Edit. Text widgets support the standard Motif editing characters + plus many Emacs editing characters. Backspace and Control-h erase the + character to the left of the insertion cursor. Delete and Control-d + erase the character to the right of the insertion cursor. Meta-backspace + deletes the word to the left of the insertion cursor, and Meta-d deletes + the word to the right of the insertion cursor. Control-k deletes from + the insertion cursor to the end of the line, or it deletes the newline + character if that is the only thing left on the line. Control-o opens + a new line by inserting a newline character to the right of the insertion + cursor. Control-t transposes the two characters on either side of the + insertion cursor. + + 7. Resize the window. This widget has been configured with the "setGrid" + option on, so that if you resize the window it will always resize to an + even number of characters high and wide. Also, if you make the window + narrow you can see that long lines automatically wrap around onto + additional lines so that all the information is always visible.} \ + {$B$3$N%&%#%s%I%&$O%F%-%9%H(B widget $B$G$9!#(B1$B9T$^$?$O$=$l0J>e$N%F%-%9%H$rI=(B + $B<(!&JT=8$9$k$3$H$,$G$-$^$9!#0J2<$O%F%-%9%H(B widget $B$G$G$-$kA`:n$K$D$$$F(B + $B$^$H$a$?$b$N$G$9!#(B + + 1. $B%9%/%m!<%k!#%9%/%m!<%k%P!<$G%F%-%9%H$NI=<(ItJ,$rF0$+$9$3$H$,$G$-$^$9!#(B + + 2. $B%9%-%c%K%s%0!#%F%-%9%H$N%&%#%s%I%&$G%^%&%9%\%?%s(B2 ($BCf%\%?%s$r(B) $B$r2!(B + $B$7$F>e2<$K%I%i%C%0$7$F$/$@$5$$!#$=$&$9$k$H%F%-%9%H$,9bB.$G%I%i%C%0$5$l!"(B + $BFbMF$r$6$C$HD/$a$k$3$H$,$G$-$^$9!#(B + + 3. $B%F%-%9%H$NA^F~!#%^%&%9%\%?%s(B1 ($B:8%\%?%s(B) $B$r2!$7!"A^F~%+!<%=%k$r%;%C(B + $B%H$7$F$+$i%F%-%9%H$rF~NO$7$F$/$@$5$$!#F~NO$7$?$b$N$,(B widget $B$KF~$j$^$9!#(B + + 4. $BA*Br!#$"$kHO0O$NJ8;z$rA*Br$9$k$K$O%^%&%9%\%?%s(B1 $B$r2!$7!"%I%i%C%0$7(B + $B$F$/$@$5$$!#0lEY%\%?%s$rN%$7$?$i!"%7%U%H%-!<$r2!$7$J$,$i%\%?%s(B1 $B$r2!$9(B + $B$3$H$GA*BrHO0O$ND4@0$,$G$-$^$9!#$3$l$OA*BrHO0O$N:G8e$r%^%&%9%+!<%=%k$K(B + $B:G$b6a$$0LCV$K%j%;%C%H$7!"%\%?%s$rN%$9A0$K%^%&%9$r%I%i%C%0$9$k$3$H$G$5(B + $B$i$KA*BrHO0O$rD4@0$G$-$^$9!#%@%V%k%/%j%C%/$G%o!<%I$r!"$^$?%H%j%W%k%/%j%C(B + $B%/$G9TA4BN$rA*Br$9$k$3$H$,$G$-$^$9!#(B + + 5. $B>C5n$HCV49!#%F%-%9%H$r>C5n$9$k$K$O!">C5n$7$?$$J8;z$rA*Br$7$F%P%C%/(B + $B%9%Z!<%9$+%G%j!<%H%-!<$rF~NO$7$F$/$@$5$$!#$"$k$$$O!"?7$7$$%F%-%9%H$r(B + $BF~NO$9$k$HA*Br$5$l$?%F%-%9%H$HCV49$5$l$^$9!#(B + + 6. $BA*BrItJ,$N%3%T!l9g$O!"2~9T$r:o=|$7$^$9!#(B + + 8. $B%&%#%s%I%&$N%j%5%$%:!#$3$N(B widget $B$O(B "setGrid" $B%*%W%7%g%s$r%*%s$K$7(B + $B$F$"$j$^$9$N$G!"%&%#%s%I%&$r%j%5%$%:$9$k;~$K$O9b$5$HI}$O>o$KJ8;z9b$HJ8(B + $B;zI}$N@0?tG\$K$J$j$^$9!#$^$?!"%&%#%s%I%&$r69$/$7$?>l9g$K$OD9$$9T$,<+F0(B + $BE*$K@^$jJV$5$l!">o$KA4$F$NFbMF$,8+$($k$h$&$K$J$C$F$$$^$9!#(B}] + $w.text mark set insert 0.0 diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/timer ./library/demos.jp/timer *** ../../tk8.0.5/library/demos.jp/timer Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/timer Thu Apr 1 00:08:43 1999 *************** *** 0 **** --- 1,40 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # timer -- + # This script generates a counter with start and stop buttons. + # + # RCS: @(#) $Id: timer,v 1.1 1999/03/31 15:08:43 m-hirano Exp $ + + label .counter -text 0.00 -relief raised -width 10 + button .start -text Start -command { + if $stopped { + set stopped 0 + tick + } + } + button .stop -text Stop -command {set stopped 1} + pack .counter -side bottom -fill both + pack .start -side left -fill both -expand yes + pack .stop -side right -fill both -expand yes + + set seconds 0 + set hundredths 0 + set stopped 1 + + proc tick {} { + global seconds hundredths stopped + if $stopped return + after 50 tick + set hundredths [expr $hundredths+5] + if {$hundredths >= 100} { + set hundredths 0 + set seconds [expr $seconds+1] + } + .counter config -text [format "%d.%02d" $seconds $hundredths] + } + + bind . {destroy .} + bind . {destroy .} + focus . diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/twind.tcl ./library/demos.jp/twind.tcl *** ../../tk8.0.5/library/demos.jp/twind.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/twind.tcl Thu Apr 1 00:08:43 1999 *************** *** 0 **** --- 1,228 ---- + # twind.tcl -- + # + # This demonstration script creates a text widget with a bunch of + # embedded windows. + # + # RCS: @(#) $Id: twind.tcl,v 1.1 1999/03/31 15:08:43 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .twind + catch {destroy $w} + toplevel $w + wm title $w "Text Demonstration - Embedded Windows" + wm iconname $w "Embedded Windows" + positionWindow $w + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.f -highlightthickness 2 -borderwidth 2 -relief sunken + set t $w.f.text + text $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \ + -height 35 -wrap word -highlightthickness 0 -borderwidth 0 + pack $t -expand yes -fill both + scrollbar $w.scroll -command "$t yview" + pack $w.scroll -side right -fill y + pack $w.f -expand yes -fill both + $t tag configure center -justify center -spacing1 5m -spacing3 5m + $t tag configure buttons -lmargin1 1c -lmargin2 1c -rmargin 1c \ + -spacing1 3m -spacing2 0 -spacing3 0 + + button $t.on -text [langSel "Turn On" "$BM-8z(B"] -command "textWindOn $w" \ + -cursor top_left_arrow + button $t.off -text [langSel "Turn Off" "$BL58z(B"] -command "textWindOff $w" \ + -cursor top_left_arrow + button $t.click -text [langSel "Clock Here" "$B$3$3$r%/%j%C%/(B"] -command "textWindPlot $t" \ + -cursor top_left_arrow + button $t.delete -text [langSel "Delete" "$B:o=|(B"] -command "textWindDel $w" \ + -cursor top_left_arrow + + langSwitch { + $t insert end "A text widget can contain other widgets embedded " + $t insert end "it. These are called \"embedded windows\", " + $t insert end "and they can consist of arbitrary widgets. " + $t insert end "For example, here are two embedded button " + $t insert end "widgets. You can click on the first button to " + $t window create end -window $t.on + $t insert end " horizontal scrolling, which also turns off " + $t insert end "word wrapping. Or, you can click on the second " + $t insert end "button to\n" + $t window create end -window $t.off + $t insert end " horizontal scrolling and turn back on word wrapping.\n\n" + + $t insert end "Or, here is another example. If you " + $t window create end -window $t.click + $t insert end " a canvas displaying an x-y plot will appear right here." + $t mark set plot insert + $t mark gravity plot left + $t insert end " You can drag the data points around with the mouse, " + $t insert end "or you can click here to " + $t window create end -window $t.delete + $t insert end " the plot again.\n\n" + + $t insert end "You may also find it useful to put embedded windows in " + $t insert end "a text without any actual text. In this case the " + $t insert end "text widget acts like a geometry manager. For " + $t insert end "example, here is a collection of buttons laid out " + $t insert end "neatly into rows by the text widget. These buttons " + $t insert end "can be used to change the background color of the " + $t insert end "text widget (\"Default\" restores the color to " + $t insert end "its default). If you click on the button labeled " + $t insert end "\"Short\", it changes to a longer string so that " + $t insert end "you can see how the text widget automatically " + $t insert end "changes the layout. Click on the button again " + $t insert end "to restore the short string.\n" + } { + $t insert end "$B%F%-%9%H(Bwidget$B>e$KB>$N(Bwidget$B$rAH$_9~$`$3$H$,$G$-$^$9!#(B" + $t insert end "$BAH$_9~$_%&%#%s%I%&$H8F$P$l!"G$0U$N(Bwidget$B$,2DG=$G$9!#(B" + $t insert end "$BNc$($P!"$3$3$K(B2$B$D$N%\%?%s(Bwidget$B$,AH$_9~$^$l$F$$$^$9!#(B" + $t insert end "$B:G=i$N%\%?%s$r%/%j%C%/$9$H?eJ?J}8~$N%9%/%m!<%k$r(B" + $t window create end -window $t.on + $t insert end "$B$K$7$^$9!#$^$?(B2$B$D$a$N%\%?%s$r%/%j%C%/$9$k$H(B" + $t insert end "$B?eJ?J}8~$N%9%/%m!<%k$r(B\n" + $t window create end -window $t.off + $t insert end "$B$K$7$^$9!#(B\n\n" + + $t insert end "$B$b$&$R$H$D$NNc$G$9!#(B" + $t window create end -window $t.click + $t insert end "$B$9$k$H!"(Bx-y$B%W%m%C%H$,$3$3$K8=$l$^$9!#(B" + $t mark set plot insert + $t mark gravity plot left + $t insert end "$B%^%&%9$G%G!<%?%]%$%s%H$r%I%i%C%0$9$k$3$H$,$G$-$^$9!#(B" + $t window create end -window $t.delete + $t insert end "$B$r%/%j%C%/$9$k$H85$KLa$j$^$9!#(B\n\n" + + $t insert end "$BAH$_9~$_%&%#%s%I%&$@$1$r%F%-%9%H(Bwidget$B>e$K!"l9g$O!"%F%-%9%H(Bwidget$B$O%&%#%s%I%&%^%M!<%8%c$N(B" + $t insert end "$B$h$&$KF0:n$7$^$9!#Nc$($P!"$3$3$K$O%F%-%9%H(Bwidget$B$K(B" + $t insert end "$B$h$C$F%\%?%s$,$-$l$$$KJB$Y$i$l$F$$$^$9!#(B" + $t insert end "$B$3$l$i$N%\%?%s$GGX7J?'$rJQ$($k$3$H$,$G$-$^$9(B" + $t insert end "(\"Default\"$B$G85$N?'$KLa$9$3$H$,$G$-$^$9(B)$B!#(B" + $t insert end "\"Short\" $B$H$$$&%\%?%s$r%/%j%C%/$9$k$HJ8;zNs$ND9$5$,JQ$o(B" + $t insert end "$B$j$^$9!#$9$k$H<+F0E*$K%F%-%9%H(Bwidget$B$,%l%$%"%&%H(B" + $t insert end "$B$r@0$($F$/$l$^$9!#$b$&0lEYF1$8%\%?%s$r2!$9$H85$KLa$j$^$9!#(B\n" + } + + button $t.default -text Default -command "embDefBg $t" \ + -cursor top_left_arrow + $t window create end -window $t.default -padx 3 + global embToggle + set embToggle Short + checkbutton $t.toggle -textvariable embToggle -indicatoron 0 \ + -variable embToggle -onvalue "A much longer string" \ + -offvalue "Short" -cursor top_left_arrow -pady 5 -padx 2 + $t window create end -window $t.toggle -padx 3 -pady 2 + set i 1 + foreach color {AntiqueWhite3 Bisque1 Bisque2 Bisque3 Bisque4 + SlateBlue3 RoyalBlue1 SteelBlue2 DeepSkyBlue3 LightBlue1 + DarkSlateGray1 Aquamarine2 DarkSeaGreen2 SeaGreen1 + Yellow1 IndianRed1 IndianRed2 Tan1 Tan4} { + button $t.color$i -text $color -cursor top_left_arrow -command \ + "$t configure -bg $color" + $t window create end -window $t.color$i -padx 3 -pady 2 + incr i + } + $t tag add buttons $t.default end + + proc textWindOn w { + catch {destroy $w.scroll2} + set t $w.f.text + scrollbar $w.scroll2 -orient horizontal -command "$t xview" + pack $w.scroll2 -after $w.buttons -side bottom -fill x + $t configure -xscrollcommand "$w.scroll2 set" -wrap none + } + + proc textWindOff w { + catch {destroy $w.scroll2} + set t $w.f.text + $t configure -xscrollcommand {} -wrap word + } + + proc textWindPlot t { + set c $t.c + if [winfo exists $c] { + return + } + canvas $c -relief sunken -width 450 -height 300 -cursor top_left_arrow + + set font {Helvetica 18} + + $c create line 100 250 400 250 -width 2 + $c create line 100 250 100 50 -width 2 + $c create text 225 20 -text [langSel "A Simple Plot" "$B4JC1$J%W%m%C%H(B"] -font $font -fill brown + + for {set i 0} {$i <= 10} {incr i} { + set x [expr {100 + ($i*30)}] + $c create line $x 250 $x 245 -width 2 + $c create text $x 254 -text [expr 10*$i] -anchor n -font $font + } + for {set i 0} {$i <= 5} {incr i} { + set y [expr {250 - ($i*40)}] + $c create line 100 $y 105 $y -width 2 + $c create text 96 $y -text [expr $i*50].0 -anchor e -font $font + } + + foreach point {{12 56} {20 94} {33 98} {32 120} {61 180} + {75 160} {98 223}} { + set x [expr {100 + (3*[lindex $point 0])}] + set y [expr {250 - (4*[lindex $point 1])/5}] + set item [$c create oval [expr $x-6] [expr $y-6] \ + [expr $x+6] [expr $y+6] -width 1 -outline black \ + -fill SkyBlue2] + $c addtag point withtag $item + } + + $c bind point "$c itemconfig current -fill red" + $c bind point "$c itemconfig current -fill SkyBlue2" + $c bind point <1> "embPlotDown $c %x %y" + $c bind point "$c dtag selected" + bind $c "embPlotMove $c %x %y" + while {[string first [$t get plot] " \t\n"] >= 0} { + $t delete plot + } + $t insert plot "\n" + $t window create plot -window $c + $t tag add center plot + $t insert plot "\n" + } + + set embPlot(lastX) 0 + set embPlot(lastY) 0 + + proc embPlotDown {w x y} { + global embPlot + $w dtag selected + $w addtag selected withtag current + $w raise current + set embPlot(lastX) $x + set embPlot(lastY) $y + } + + proc embPlotMove {w x y} { + global embPlot + $w move selected [expr $x-$embPlot(lastX)] [expr $y-$embPlot(lastY)] + set embPlot(lastX) $x + set embPlot(lastY) $y + } + + proc textWindDel w { + set t $w.f.text + if [winfo exists $t.c] { + $t delete $t.c + while {[string first [$t get plot] " \t\n"] >= 0} { + $t delete plot + } + $t insert plot " " + } + } + + proc embDefBg t { + $t configure -background [lindex [$t configure -background] 3] + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/vscale.tcl ./library/demos.jp/vscale.tcl *** ../../tk8.0.5/library/demos.jp/vscale.tcl Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/vscale.tcl Thu Apr 1 00:08:44 1999 *************** *** 0 **** --- 1,50 ---- + # vscale.tcl -- + # + # This demonstration script shows an example with a vertical scale. + # + # RCS: @(#) $Id: vscale.tcl,v 1.1 1999/03/31 15:08:44 m-hirano Exp $ + + if {![info exists widgetDemo]} { + error "This script should be run from the \"widget\" demo." + } + + set w .vscale + catch {destroy $w} + toplevel $w + wm title $w "Vertical Scale Demonstration" + wm iconname $w "vscale" + positionWindow $w + + label $w.msg -font $font -wraplength 3.5i -justify left -text [langSel \ + "An arrow and a vertical scale are displayed below. If you click or drag mouse button 1 in the scale, you can change the size of the arrow." \ + "$B2<$K$O%P!<$H=D7?$N%9%1!<%k$,I=<($5$l$F$$$^$9!#%9%1!<%k$G%^%&%9$N%\%?%s(B1 $B$r%/%j%C%/$9$k$+%I%i%C%0$7$F%P!<$N9b$5$rJQ$($k$3$H$,$G$-$^$9!#=*$C$?$i!VN;2r!W%\%?%s$r2!$7$F$/$@$5$$!#(B"] + pack $w.msg -side top -padx .5c + + frame $w.buttons + pack $w.buttons -side bottom -fill x -pady 2m + button $w.buttons.dismiss -text [langSel Dismiss $BN;2r(B] -command "destroy $w" + button $w.buttons.code -text [langSel "See Code" "$B%3!<%I;2>H(B"] -command "showCode $w" + pack $w.buttons.dismiss $w.buttons.code -side left -expand 1 + + frame $w.frame -borderwidth 10 + pack $w.frame + + scale $w.frame.scale -orient vertical -length 284 -from 0 -to 250 \ + -command "setHeight $w.frame.canvas" -tickinterval 50 + canvas $w.frame.canvas -width 50 -height 50 -bd 0 -highlightthickness 0 + $w.frame.canvas create polygon 0 0 1 1 2 2 -fill SeaGreen3 -tags poly + $w.frame.canvas create line 0 0 1 1 2 2 0 0 -fill black -tags line + frame $w.frame.right -borderwidth 15 + pack $w.frame.scale -side left -anchor ne + pack $w.frame.canvas -side left -anchor nw -fill y + $w.frame.scale set 75 + + proc setHeight {w height} { + incr height 21 + set y2 [expr $height - 30] + if {$y2 < 21} { + set y2 21 + } + $w coords poly 15 20 35 20 35 $y2 45 $y2 25 $height 5 $y2 15 $y2 15 20 + $w coords line 15 20 35 20 35 $y2 45 $y2 25 $height 5 $y2 15 $y2 15 20 + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/demos.jp/widget ./library/demos.jp/widget *** ../../tk8.0.5/library/demos.jp/widget Thu Jan 1 09:00:00 1970 --- ./library/demos.jp/widget Sat Apr 10 05:07:05 1999 *************** *** 0 **** --- 1,593 ---- + #!/bin/sh + # the next line restarts using wish \ + exec wish "$0" "$@" + + # widget -- + # This script demonstrates the various widgets provided by Tk, + # along with many of the features of the Tk toolkit. This file + # only contains code to generate the main window for the + # application, which invokes individual demonstrations. The + # code for the actual demonstrations is contained in separate + # ".tcl" files is this directory, which are sourced by this script + # as needed. + # + # RCS: @(#) $Id: widget,v 1.4 1999/04/08 01:24:53 m-hirano Exp $ + + eval destroy [winfo child .] + wm title . "Widget Demonstration" + set widgetDemo 1 + + # setup fonts, kinsoku + if {[info commands kanji] != {}} { + if {$tcl_platform(platform) == "windows"} { + foreach p {10 12 14 18 24} { + font create @kanji${p} -copy [list {$B#M#S(B $B#P%4%7%C%/(B} $p] + font create @kanji${p}b -copy [list {$B#M#S(B $B#P%4%7%C%/(B} $p bold] + font create @kanji${p}bi -copy [list {$B#M#S(B $B#P%4%7%C%/(B} $p bold italic] + } + } else { + set aSize(10) 10 + set aSize(12) 13 + set aSize(14) 13 + set aSize(18) 15 + set aSize(24) 23 + foreach p {10 12 14 18 24} { + font create @kanji$p -charset jisx0208.1983 -size $aSize($p) + font create @kanji${p}b -charset jisx0208.1983 -size $aSize($p) -weight bold + font create @kanji${p}bi -charset jisx0208.1983 -size $aSize($p) -weight bold -slant italic + } + } + font create Helvetica10 -compound {{Helvetica 10} @kanji10} + font create Courier12bolditalic -compound {{Courier 12 bold italic} @kanji12bi} + font create Helvetica12 -compound {{Helvetica 12} @kanji12} + font create Courier14bold -compound {{Courier 14 bold} @kanji14b} + font create Helvetica14 -compound {{Helvetica 14} @kanji14} + font create Helvetica18 -compound {{Helvetica 18} @kanji18} + font create Helvetica18bold -compound {{Helvetica 18 bold} @kanji18b} + font create Helvetica24 -compound {{Helvetica 24} @kanji24} + font create Helvetica24bold -compound {{Helvetica 24 bold} @kanji24b} + + kinsoku add begin \ + "$B$!(B" "$B$#(B" "$B$%(B" "$B$'(B" "$B$)(B" "$B$c(B" "$B$e(B" "$B$g(B" "$B$C(B" \ + "$B%!(B" "$B%#(B" "$B%%(B" "$B%'(B" "$B%)(B" "$B%c(B" "$B%e(B" "$B%g(B" "$B%C(B" \ + "$B!<(B" + kinsoku add end \ + "\"" + } else { + font create Helvetica10 -family Helvetica -size 10 + font create Courier12bolditalic -family Courier -size 12 -weight bold -slant italic + font create Helvetica12 -family Helvetica -size 12 + font create Courier14bold -family Courier -size 14 -weight bold + font create Helvetica14 -family Helvetica -size 14 + font create Helvetica18 -family Helvetica -size 18 + font create Helvetica18bold -family Helvetica -size 18 -weight bold + font create Helvetica24 -family Helvetica -size 24 + font create Helvetica24bold -family Helvetica -size 24 -weight bold + } + #---------------------------------------------------------------- + # The code below create the main window, consisting of a menu bar + # and a text widget that explains how to use the program, plus lists + # all of the demos as hypertext items. + #---------------------------------------------------------------- + + set font {Helvetica14} + menu .menuBar -tearoff 0 + .menuBar add cascade -menu .menuBar.file -label "File" -underline 0 + menu .menuBar.file -tearoff 0 + + # On the Mac use the specia .apple menu for the about item + if {$tcl_platform(platform) == "macintosh"} { + .menuBar add cascade -menu .menuBar.apple + menu .menuBar.apple -tearoff 0 + .menuBar.apple add command -label "About..." -command "aboutBox" + } else { + .menuBar.file add command -label "About..." -command "aboutBox" \ + -underline 0 -accelerator "" + .menuBar.file add sep + } + + .menuBar.file add command -label "Quit" -command "exit" -underline 0 \ + -accelerator "Meta-Q" + . configure -menu .menuBar + bind . aboutBox + + # Create Lang Menu + .menuBar add cascade -menu .menuBar.lang -label "Lang" -underline 0 + menu .menuBar.lang -tearoff 0 + foreach lang {{English {}} {Japanese jp}} { + .menuBar.lang add radiobutton -label [lindex $lang 0] \ + -variable demoLang -value [lindex $lang 1] \ + -command "setContents" -underline 0 + } + # default language + set demoLang jp + + # select/switch by language + proc langSel {defaultValue jpValue} { + global demoLang + if {$demoLang == "jp"} { + return $jpValue + } + return $defaultValue + } + proc langSwitch {defaultCode jpCode} { + uplevel [langSel $defaultCode $jpCode] + } + # select by japanized or not. + proc jp&orig {jp orig} { + if { [ string length [ info commands kanji ] ] <= 0 } { + return $orig + } else { + return $jp + } + } + + frame .statusBar + label .statusBar.lab -text " " -relief sunken -bd 1 \ + -font Helvetica10 -anchor w + label .statusBar.foo -width 8 -relief sunken -bd 1 \ + -font Helvetica10 -anchor w + pack .statusBar.lab -side left -padx 2 -expand yes -fill both + pack .statusBar.foo -side left -padx 2 + pack .statusBar -side bottom -fill x -pady 2 + + frame .textFrame + scrollbar .s -orient vertical -command {.t yview} -highlightthickness 0 \ + -takefocus 1 + pack .s -in .textFrame -side right -fill y + text .t -yscrollcommand {.s set} -wrap word -width 60 -height 30 -font $font \ + -setgrid 1 -highlightthickness 0 -padx 4 -pady 2 -takefocus 0 + pack .t -in .textFrame -expand y -fill both -padx 1 + pack .textFrame -expand yes -fill both + + # Create a bunch of tags to use in the text widget, such as those for + # section titles and demo descriptions. Also define the bindings for + # tags. + + .t tag configure title -font {Helvetica18bold} + + # We put some "space" characters to the left and right of each demo description + # so that the descriptions are highlighted only when the mouse cursor + # is right over them (but not when the cursor is to their left or right) + # + .t tag configure demospace -lmargin1 1c -lmargin2 1c + + + if {[winfo depth .] == 1} { + .t tag configure demo -lmargin1 1c -lmargin2 1c \ + -underline 1 + .t tag configure visited -lmargin1 1c -lmargin2 1c \ + -underline 1 + .t tag configure hot -background black -foreground white + } else { + .t tag configure demo -lmargin1 1c -lmargin2 1c \ + -foreground blue -underline 1 + .t tag configure visited -lmargin1 1c -lmargin2 1c \ + -foreground #303080 -underline 1 + .t tag configure hot -foreground red -underline 1 + } + .t tag bind demo { + invoke [.t index {@%x,%y}] + } + set lastLine "" + .t tag bind demo { + set lastLine [.t index {@%x,%y linestart}] + .t tag add hot "$lastLine +1 chars" "$lastLine lineend -1 chars" + .t config -cursor hand2 + showStatus [.t index {@%x,%y}] + } + .t tag bind demo { + .t tag remove hot 1.0 end + .t config -cursor xterm + .statusBar.lab config -text "" + } + .t tag bind demo { + set newLine [.t index {@%x,%y linestart}] + if {[string compare $newLine $lastLine] != 0} { + .t tag remove hot 1.0 end + set lastLine $newLine + + set tags [.t tag names {@%x,%y}] + set i [lsearch -glob $tags demo-*] + if {$i >= 0} { + .t tag add hot "$lastLine +1 chars" "$lastLine lineend -1 chars" + } + } + showStatus [.t index {@%x,%y}] + } + + # Create the text for the text widget. + + proc setContents {} { + .t configure -state normal + .t delete 1.0 end + langSwitch { + .t insert end "Tk Widget Demonstrations\n" title + .t insert end { + This application provides a front end for several short scripts that demonstrate what you can do with Tk widgets. Each of the numbered lines below describes a demonstration; you can click on it to invoke the demonstration. Once the demonstration window appears, you can click the "See Code" button to see the Tcl/Tk code that created the demonstration. If you wish, you can edit the code and click the "Rerun Demo" button in the code window to reinvoke the demonstration with the modified code. + + } + .t insert end "Labels, buttons, checkbuttons, and radiobuttons" title + .t insert end " \n " {demospace} + .t insert end "1. Labels (text and bitmaps)." {demo demo-label} + .t insert end " \n " {demospace} + .t insert end "2. Buttons." {demo demo-button} + .t insert end " \n " {demospace} + .t insert end "3. Checkbuttons (select any of a group)." {demo demo-check} + .t insert end " \n " {demospace} + .t insert end "4. Radiobuttons (select one of a group)." {demo demo-radio} + .t insert end " \n " {demospace} + .t insert end "5. A 15-puzzle game made out of buttons." {demo demo-puzzle} + .t insert end " \n " {demospace} + .t insert end "6. Iconic buttons that use bitmaps." {demo demo-icon} + .t insert end " \n " {demospace} + .t insert end "7. Two labels displaying images." {demo demo-image1} + .t insert end " \n " {demospace} + .t insert end "8. A simple user interface for viewing images." \ + {demo demo-image2} + .t insert end " \n " {demospace} + + .t insert end \n {} "Listboxes" title + .t insert end " \n " {demospace} + .t insert end "1. 50 states." {demo demo-states} + .t insert end " \n " {demospace} + .t insert end "2. Colors: change the color scheme for the application." \ + {demo demo-colors} + .t insert end " \n " {demospace} + .t insert end "3. A collection of famous sayings." {demo demo-sayings} + .t insert end " \n " {demospace} + + .t insert end \n {} "Entries" title + .t insert end " \n " {demospace} + .t insert end "1. Without scrollbars." {demo demo-entry1} + .t insert end " \n " {demospace} + .t insert end "2. With scrollbars." {demo demo-entry2} + .t insert end " \n " {demospace} + .t insert end "3. Simple Rolodex-like form." {demo demo-form} + .t insert end " \n " {demospace} + + .t insert end \n {} "Text" title + .t insert end " \n " {demospace} + .t insert end "1. Basic editable text." {demo demo-text} + .t insert end " \n " {demospace} + .t insert end "2. Text display styles." {demo demo-style} + .t insert end " \n " {demospace} + .t insert end "3. Hypertext (tag bindings)." {demo demo-bind} + .t insert end " \n " {demospace} + .t insert end "4. A text widget with embedded windows." {demo demo-twind} + .t insert end " \n " {demospace} + .t insert end "5. A search tool built with a text widget." {demo demo-search} + .t insert end " \n " {demospace} + + .t insert end \n {} "Canvases" title + .t insert end " \n " {demospace} + .t insert end "1. The canvas item types." {demo demo-items} + .t insert end " \n " {demospace} + .t insert end "2. A simple 2-D plot." {demo demo-plot} + .t insert end " \n " {demospace} + .t insert end "3. Text items in canvases." {demo demo-ctext} + .t insert end " \n " {demospace} + .t insert end "4. An editor for arrowheads on canvas lines." {demo demo-arrow} + .t insert end " \n " {demospace} + .t insert end "5. A ruler with adjustable tab stops." {demo demo-ruler} + .t insert end " \n " {demospace} + .t insert end "6. A building floor plan." {demo demo-floor} + .t insert end " \n " {demospace} + .t insert end "7. A simple scrollable canvas." {demo demo-cscroll} + .t insert end " \n " {demospace} + + .t insert end \n {} "Scales" title + .t insert end " \n " {demospace} + .t insert end "1. Vertical scale." {demo demo-vscale} + .t insert end " \n " {demospace} + .t insert end "2. Horizontal scale." {demo demo-hscale} + .t insert end " \n " {demospace} + + .t insert end \n {} "Menus" title + .t insert end " \n " {demospace} + .t insert end "1. Menus and cascades." \ + {demo demo-menu} + .t insert end " \n " {demospace} + .t insert end "2. Menubuttons"\ + {demo demo-menubu} + .t insert end " \n " {demospace} + + .t insert end \n {} "Common Dialogs" title + .t insert end " \n " {demospace} + .t insert end "1. Message boxes." {demo demo-msgbox} + .t insert end " \n " {demospace} + .t insert end "2. File selection dialog." {demo demo-filebox} + .t insert end " \n " {demospace} + .t insert end "3. Color picker." {demo demo-clrpick} + .t insert end " \n " {demospace} + + .t insert end \n {} "Miscellaneous" title + .t insert end " \n " {demospace} + .t insert end "1. The built-in bitmaps." {demo demo-bitmap} + .t insert end " \n " {demospace} + .t insert end "2. A dialog box with a local grab." {demo demo-dialog1} + .t insert end " \n " {demospace} + .t insert end "3. A dialog box with a global grab." {demo demo-dialog2} + .t insert end " \n " {demospace} + if {[info commands kanji] != {}} { + .t insert end "4. Compound Font" {demo demo-cfont} + .t insert end " \n " {demospace} + } + } { + .t insert end "Tk Widget $B%G%b%s%9%H%l!<%7%g%s(B\n" title + .t insert end { + $B$3$N%"%W%j%1!<%7%g%s$O!"(BTk Widget $B$rMQ$$$F$I$N$h$&$J$3$H$,$G$-$k$+$r<($9$?$a$N!"$$$/$D$+$N>.$5$J%9%/%j%W%H$KBP$9$k%U%m%s%H%(%s%I$rDs6!$7$F$$$^$9!#0J2<$K=gHV$K5s$2$i$l$F$$$k%G%b%s%9%H%l!<%7%g%s$rH(B" $B%\%?%s$r%/%j%C%/$9$k$3$H$,$G$-$^$9!#$"$J$?$,K>$`$J$i!"$=$N%3!<%I$r=$@5$9$k$3$H$,$G$-$^$9!#=$@5$7$?%3!<%I$G%G%b%s%9%H%l!<%7%g%s$r:F(B" {demo demo-vscale} + .t insert end " \n " {demospace} + .t insert end "2. $B?eJ?(B" {demo demo-hscale} + .t insert end " \n " {demospace} + + .t insert end \n {} "$B%a%K%e!<(B" title + .t insert end " \n " {demospace} + .t insert end "1. $B%a%K%e!<$H%+%9%1!<%I(B" \ + {demo demo-menu} + .t insert end " \n " {demospace} + .t insert end "2. $B%a%K%e!<%\%?%s(B"\ + {demo demo-menubu} + .t insert end " \n " {demospace} + + .t insert end \n {} "$B%3%b%s%@%$%"%m%0(B" title + .t insert end " \n " {demospace} + .t insert end "1. $B%a%C%;!<%8%\%C%/%9(B" {demo demo-msgbox} + .t insert end " \n " {demospace} + .t insert end "2. $B%U%!%$%kA*Br%@%$%"%m%0(B" {demo demo-filebox} + .t insert end " \n " {demospace} + .t insert end "3. $B?'A*Br%@%$%"%m%0(B" {demo demo-clrpick} + .t insert end " \n " {demospace} + + .t insert end \n {} "$B$=$NB>(B" title + .t insert end " \n " {demospace} + .t insert end "1. $BAH$_9~$_$N%S%C%H%^%C%W(B" {demo demo-bitmap} + .t insert end " \n " {demospace} + .t insert end "2. $B%b!<%@%k%@%$%"%m%0(B($B%m!<%+%k%0%i%V(B)" {demo demo-dialog1} + .t insert end " \n " {demospace} + .t insert end "3. $B%b!<%@%k%@%$%"%m%0(B($B%0%m!<%P%k%0%i%V(B)" {demo demo-dialog2} + .t insert end " \n " {demospace} + if {[info commands kanji] != {}} { + .t insert end "4. $B%3%s%Q%&%s%I%U%)%s%H(B" {demo demo-cfont} + .t insert end " \n " {demospace} + } + } + .t configure -state disabled + } + setContents + + .t configure -state disabled + focus .s + + # positionWindow -- + # This procedure is invoked by most of the demos to position a + # new demo window. + # + # Arguments: + # w - The name of the window to position. + + proc positionWindow w { + wm geometry $w +300+300 + } + + # showVars -- + # Displays the values of one or more variables in a window, and + # updates the display whenever any of the variables changes. + # + # Arguments: + # w - Name of new window to create for display. + # args - Any number of names of variables. + + proc showVars {w args} { + catch {destroy $w} + toplevel $w + wm title $w "Variable values" + label $w.title -text [langSel "Variable values:" "$BJQ?tCM(B:"] -width 20 -anchor center \ + -font {Helvetica18} + pack $w.title -side top -fill x + set len 1 + foreach i $args { + if {[string length $i] > $len} { + set len [string length $i] + } + } + foreach i $args { + frame $w.$i + label $w.$i.name -text "$i: " -width [expr $len + 2] -anchor w + label $w.$i.value -textvar $i -anchor w + pack $w.$i.name -side left + pack $w.$i.value -side left -expand 1 -fill x + pack $w.$i -side top -anchor w -fill x + } + button $w.ok -text OK -command "destroy $w" -default active + bind $w "tkButtonInvoke $w.ok" + pack $w.ok -side bottom -pady 2 + } + + # invoke -- + # This procedure is called when the user clicks on a demo description. + # It is responsible for invoking the demonstration. + # + # Arguments: + # index - The index of the character that the user clicked on. + + proc invoke index { + global tk_library + set tags [.t tag names $index] + set i [lsearch -glob $tags demo-*] + if {$i < 0} { + return + } + set cursor [.t cget -cursor] + .t configure -cursor watch + update + set demo [string range [lindex $tags $i] 5 end] + uplevel [list source [file join $tk_library demos.jp $demo.tcl]] + update + .t configure -cursor $cursor + + .t tag add visited "$index linestart +1 chars" "$index lineend -1 chars" + } + + # showStatus -- + # + # Show the name of the demo program in the status bar. This procedure + # is called when the user moves the cursor over a demo description. + # + proc showStatus index { + global tk_library + set tags [.t tag names $index] + set i [lsearch -glob $tags demo-*] + set cursor [.t cget -cursor] + if {$i < 0} { + .statusBar.lab config -text " " + set newcursor xterm + } else { + set demo [string range [lindex $tags $i] 5 end] + .statusBar.lab config -text [langSel "Run the \"$demo\" sample program" "$B%5%s%W%k%W%m%0%i%`(B \"$demo\" $B$r 0 } { + # use default font family + $w.msg configure -font [lreplace [$w.msg cget -font] end end 18] + } else { + $w.msg configure -font {Times 18} + } } else { ! if { [ string length [ info command kanji ] ] > 0 } { ! if { [ lsearch [ font names ] Mincho:Times-18 ] < 0 } { ! font create Mincho:Times-18 -compound {{Times 18} kanji16} ! } ! $w.msg configure -font Mincho:Times-18 ! } else { ! $w.msg configure -font {Times 18} ! } } pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m if {$bitmap != ""} { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/entry.tcl ./library/entry.tcl *** ../../tk8.0.5/library/entry.tcl Tue Sep 15 03:23:23 1998 --- ./library/entry.tcl Fri Mar 12 00:37:25 1999 *************** *** 32,38 **** # The code below creates the default class bindings for entries. #------------------------------------------------------------------------- bind Entry <> { ! if {![catch {set data [string range [%W get] [%W index sel.first]\ [expr {[%W index sel.last] - 1}]]}]} { clipboard clear -displayof %W clipboard append -displayof %W $data --- 32,43 ---- # The code below creates the default class bindings for entries. #------------------------------------------------------------------------- bind Entry <> { ! if {[info commands kstring] != {}} { ! set stringCmd kstring ! } else { ! set stringCmd string ! } ! if {![catch {set data [$stringCmd range [%W get] [%W index sel.first]\ [expr {[%W index sel.last] - 1}]]}]} { clipboard clear -displayof %W clipboard append -displayof %W $data *************** *** 40,46 **** } } bind Entry <> { ! if {![catch {set data [string range [%W get] [%W index sel.first]\ [expr {[%W index sel.last] - 1}]]}]} { clipboard clear -displayof %W clipboard append -displayof %W $data --- 45,56 ---- } } bind Entry <> { ! if {[info commands kstring] != {}} { ! set stringCmd kstring ! } else { ! set stringCmd string ! } ! if {![catch {set data [$stringCmd range [%W get] [%W index sel.first]\ [expr {[%W index sel.last] - 1}]]}]} { clipboard clear -displayof %W clipboard append -displayof %W $data *************** *** 554,560 **** if {$first < 0} { return } ! set new [string index [$w get] [expr {$i-1}]][string index [$w get] $first] $w delete $first $i $w insert insert $new tkEntrySeeInsert $w --- 564,575 ---- if {$first < 0} { return } ! if {[info commands kstring] != {}} { ! set stringCmd kstring ! } else { ! set stringCmd string ! } ! set new [$stringCmd index [$w get] [expr {$i-1}]][$stringCmd index [$w get] $first] $w delete $first $i $w insert insert $new tkEntrySeeInsert $w diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/kinput.tcl ./library/kinput.tcl *** ../../tk8.0.5/library/kinput.tcl Thu Jan 1 09:00:00 1970 --- ./library/kinput.tcl Fri Mar 12 00:37:26 1999 *************** *** 0 **** --- 1,308 ---- + # kinput.tcl -- + # + # This file contains Tcl procedures used to input Japanese text. + # + # $Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/library/kinput.tcl,v 1.10 1999/03/11 15:37:26 m-hirano Exp $ + # + # Copyright (c) 1993, 1999 Software Research Associates, Inc. + # + # Permission to use, copy, modify, and distribute this software and its + # documentation for any purpose and without fee is hereby granted, provided + # that the above copyright notice appear in all copies and that both that + # copyright notice and this permission notice appear in supporting + # documentation, and that the name of Software Research Associates not be + # used in advertising or publicity pertaining to distribution of the + # software without specific, written prior permission. Software Research + # Associates makes no representations about the suitability of this software + # for any purpose. It is provided "as is" without express or implied + # warranty. + # + + # Get class specific Kinput conversion style. + set kiStyle(Text) over + set kiStyle(Entry) over + foreach i {Text Entry} { + set style [option get . tkKinputStyle($i) *] + if {[string length $style] > 0} { + set style [string tolower $style] + if {[string compare $style "root"] == 0 || + [string compare $style "over"]} { + set kiStyle($i) $style + } + } + } + + # Get conversion start keys from X resource database. + set KIStart [option get . tkKinputStartKeys *] + if {[string length $KIStart] > 0} { + # try to bind with the keys to check whether it is valid or not. + foreach i $KIStart { + if {[regexp {^<.*>$} $i] == 0} { + set i <${i}> + } + set tmp "" + if {[catch {bind . $i {puts dummy}} tmp] == 0} { + catch {bind . $i ""} + lappend valids $i + } else { + puts stderr "$tmp" + } + catch {unset tmp} + } + if {[string length $valids] > 0} { + set KIStart $valids + } + } else { + set KIStart " " + } + + # ---------------------------------------------------------------------- + # Class bindings for start Japanese text input (Kana-Kanji conversion). + # Use over-the-spot style for both text and entry widgets. + # ---------------------------------------------------------------------- + set tStyle $kiStyle(Text) + set eStyle $kiStyle(Entry) + foreach i $KIStart { + bind Text $i "kinput_start %W $tStyle" + bind Entry $i "kinput_start %W $eStyle" + } + unset KIStart tStyle eStyle + unset kiStyle(Text) + unset kiStyle(Entry) + catch {unset kiStyle} + + # The procedure below is invoked in order to start Japanese text input + # for the specified widget. It sends a request to the input server to + # start conversion on that widget. + # Second argument specifies input style. Valid values are "over" (for + # over-the-spot style) and "root" (for root window style). See X11R5 + # Xlib manual for the meaning of these styles). The default is root + # window style. + + proc kinput_start { w {style root} } { + update + global _kinput_priv + if { ![ string compare $style "over" ] } { + set spot [ $w xypos insert ] + if { [ string length $spot ] <= 0 } { + set spot "[ $w cget -bo ] [ winfo height $w ]" + } + set font [ $w cget -font ] + set attr [ font actual $font ] + set compound [ lindex $attr end ] + if { [ llength $compound ] < 1 } { + set font "{$font}" + } + trace variable _kinput_priv($w) w _kinput_trace_over + kanjiInput start $w \ + -variable _kinput_priv($w) \ + -inputStyle over \ + -foreground [ $w cget -foreground ] \ + -background [ $w cget -background ] \ + -fonts "$font" \ + -clientArea [_kinput_area $w] \ + -spot $spot + return + } + trace variable _kinput_priv($w) w _kinput_trace_root + kanjiInput start $w -variable _kinput_priv($w) -inputStyle root + } + + # The procedure below is invoked to send the spot location (the XY + # coordinate of the point where characters to be inserted) to the + # input server. It should be called whenever the location has + # been changed while in over-the-spot conversion mode. + + proc kinput_send_spot {w} { + if { [ catch { kanjiInput attribute $w } ] == 0 } { + set spot [_kinput_spot $w] + if { [ string length $spot ] > 0 } then { + kanjiInput attribute $w -spot $spot + } + } + } + + # + # All of the procedures below are the internal procedures for this + # package. + # + + # The following procedure returns the list of XY coordinate of the + # current insertion point of the specified widget. + + proc _kinput_spot {w} { + $w xypos insert + } + + # The following procedure returns the list of drawing area of the + # specified widget. { x y width height } + + proc _kinput_area {w} { + set bw [ $w cget -bo ] + return "$bw $bw [expr {[winfo width $w] - $bw*2}] [expr {[winfo height $w] - $bw*2}]" + } + + # The following procedure returns the value of the specified option + # (resource). + #proc _kinput_attr {w option} {lindex [$w configure $option] 4} + proc _kinput_attr {w option} { $w cget $option } + + # The two procedures below are callbacks of a variable tracing. + # The traced variable contains the text string sent from the + # input server as a conversion result. + + # for root style + proc _kinput_trace_root {name1 name2 op} { + upvar #0 $name1 trvar + $name2 insert insert $trvar($name2) + unset $trvar($name2) + } + + # for over-the-spot style + proc _kinput_trace_over {name1 name2 op} { + upvar #0 $name1 trvar + $name2 insert insert $trvar($name2) + update + if { [ string compare [ winfo class $name2 ] "Entry" ] == 0 } { + tkEntrySetCursor $name2 insert + } else { + tkTextSetCursor $name2 insert + } + unset $trvar($name2) + } + + + # tkEntryBackspace -- redefine. + # Backspace over the character just before the insertion cursor. + # If backspacing would move the cursor off the left edge of the + # window, reposition the cursor at about the middle of the window. + # + # Arguments: + # w - The entry window in which to backspace. + + proc tkEntryBackspace w { + if {[$w selection present]} { + $w delete sel.first sel.last + } else { + set x [expr {[$w index insert] - 1}] + if {$x >= 0} {$w delete $x} + if {[$w index @0] >= [$w index insert]} { + set range [$w xview] + set left [lindex $range 0] + set right [lindex $range 1] + $w xview moveto [expr {$left - ($right - $left)/2.0}] + } + } + tkEntrySeeInsert $w + } + + + # tkEntrySeeInsert -- redefine. + # Make sure that the insertion cursor is visible in the entry window. + # If not, adjust the view so that it is. + # + # Arguments: + # w - The entry window. + + proc tkEntrySeeInsert w { + set c [$w index insert] + set left [$w index @0] + if {$left > $c} { + $w xview $c + kinput_send_spot $w + return + } + set x [winfo width $w] + while {([$w index @$x] <= $c) && ($left < $c)} { + incr left + $w xview $left + } + kinput_send_spot $w + } + + + proc tkEntryConfigureEventProc {w} { + if {[catch { kanjiInput attribute $w }] == 0} { + update + set spot [_kinput_spot $w] + set area [_kinput_area $w] + kanjiInput attribute $w -clientArea $area -spot $spot + } + } + bind Entry {tkEntryConfigureEventProc %W} + + # tkTextSetCursor - redefine. + # Move the insertion cursor to a given position in a text. Also + # clears the selection, if there is one in the text, and makes sure + # that the insertion cursor is visible. Also, don't let the insertion + # cursor appear on the dummy last line of the text. + # + # Arguments: + # w - The text window. + # pos - The desired new position for the cursor in the window. + + proc tkTextSetCursor {w pos} { + if [$w compare $pos == end] { + set pos {end - 1 chars} + } + $w mark set insert $pos + $w tag remove sel 1.0 end + $w see insert + kinput_send_spot $w + } + + proc tkTextConfigureEventProc {w} { + if {[catch { kanjiInput attribute $w }] == 0} { + update + set spot [_kinput_spot $w] + set area [_kinput_area $w] + kanjiInput attribute $w -clientArea $area -spot $spot + } + } + bind Text {tkTextConfigureEventProc %W} + + + + bind Text <1> { + tkTextButton1 %W %x %y + %W tag remove sel 0.0 end + tkTextSetCursor %W insert + } + + bind Text { + if {[%W tag nextrange sel 1.0 end] != ""} { + %W delete sel.first sel.last + tkTextSetCursor %W insert + } else { + tkTextSetCursor %W insert-1c + %W delete insert + %W see insert + } + } + + bind Text { + if {[%W tag nextrange sel 1.0 end] != ""} { + %W delete sel.first sel.last + tkTextSetCursor %W insert + } else { + tkTextSetCursor %W insert-1c + %W delete insert + %W see insert + } + } + + bind Text { + if {[%W tag nextrange sel 1.0 end] != ""} { + %W delete sel.first sel.last + tkTextSetCursor %W insert + } else { + tkTextSetCursor %W insert-1c + %W delete insert + %W see insert + } + } + + bind Text { + tkTextInsert %W \n + tkTextSetCursor %W insert + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/kinsoku.tcl ./library/kinsoku.tcl *** ../../tk8.0.5/library/kinsoku.tcl Thu Jan 1 09:00:00 1970 --- ./library/kinsoku.tcl Sat Feb 20 14:59:04 1999 *************** *** 0 **** --- 1,7 ---- + # default kinsoku table. + + + kinsoku add begin ) \] . , ? ! $B!#(B $B!"(B $B!K(B $B![(B $B!M(B $B!O(B $B!Y(B $B!W(B $B!)(B $B!*(B + + kinsoku add end ( \[ $B!J(B $B!Z(B $B!L(B $B!N(B $B!X(B $B!V(B + diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/menu.tcl ./library/menu.tcl *** ../../tk8.0.5/library/menu.tcl Fri Feb 5 05:58:40 1999 --- ./library/menu.tcl Fri Mar 12 00:37:26 1999 *************** *** 881,886 **** --- 881,891 ---- proc tkMenuFind {w char} { global tkPriv + if {[info commands kstring] != {}} { + set stringCmd kstring + } else { + set stringCmd string + } set char [string tolower $char] set windowlist [winfo child $w] *************** *** 900,908 **** if {[$child type $i] == "separator"} { continue } ! set char2 [string index [$child entrycget $i -label] \ [$child entrycget $i -underline]] ! if {([string compare $char [string tolower $char2]] \ == 0) || ($char == "")} { if {[$child entrycget $i -state] != "disabled"} { return $child --- 905,913 ---- if {[$child type $i] == "separator"} { continue } ! set char2 [$stringCmd index [$child entrycget $i -label] \ [$child entrycget $i -underline]] ! if {([$stringCmd compare $char [$stringCmd tolower $char2]] \ == 0) || ($char == "")} { if {[$child entrycget $i -state] != "disabled"} { return $child *************** *** 921,929 **** } switch [winfo class $child] { Menubutton { ! set char2 [string index [$child cget -text] \ [$child cget -underline]] ! if {([string compare $char [string tolower $char2]] == 0) || ($char == "")} { if {[$child cget -state] != "disabled"} { return $child --- 926,934 ---- } switch [winfo class $child] { Menubutton { ! set char2 [$stringCmd index [$child cget -text] \ [$child cget -underline]] ! if {([$stringCmd compare $char [$stringCmd tolower $char2]] == 0) || ($char == "")} { if {[$child cget -state] != "disabled"} { return $child *************** *** 1027,1034 **** if {$last == "none"} { return } for {set i 0} {$i <= $last} {incr i} { ! if {[catch {set char2 [string index \ [$w entrycget $i -label] \ [$w entrycget $i -underline]]}]} { continue --- 1032,1044 ---- if {$last == "none"} { return } + if {[info commands kstring] != {}} { + set stringCmd kstring + } else { + set stringCmd string + } for {set i 0} {$i <= $last} {incr i} { ! if {[catch {set char2 [$stringCmd index \ [$w entrycget $i -label] \ [$w entrycget $i -underline]]}]} { continue diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/msgbox.tcl ./library/msgbox.tcl *** ../../tk8.0.5/library/msgbox.tcl Thu Nov 12 15:22:05 1998 --- ./library/msgbox.tcl Fri Mar 12 00:37:27 1999 *************** *** 161,168 **** option add *Dialog.msg.wrapLength 3i widgetDefault label $w.msg -justify left -text $data(-message) ! catch {$w.msg configure -font \ ! -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-* } pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m if {$data(-icon) != ""} { --- 161,175 ---- option add *Dialog.msg.wrapLength 3i widgetDefault label $w.msg -justify left -text $data(-message) ! if { [ string length [ info command kanji ] ] > 0 } { ! if { [ lsearch [ font names ] Mincho:Times-18 ] < 0 } { ! font create Mincho:Times-18 -compound {{Times 18} kanji16} ! } ! catch { $w.msg configure -font Mincho:Times-18 } ! } else { ! catch {$w.msg configure -font \ ! -Adobe-Times-Medium-R-Normal--*-180-*-*-*-*-*-* ! } } pack $w.msg -in $w.top -side right -expand 1 -fill both -padx 3m -pady 3m if {$data(-icon) != ""} { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/prolog.ps ./library/prolog.ps *** ../../tk8.0.5/library/prolog.ps Fri Feb 5 05:59:48 1999 --- ./library/prolog.ps Fri Mar 12 00:37:28 1999 *************** *** 280,284 **** --- 280,399 ---- 0 spacing neg translate } forall } bind def + + + % Japanization stuff. + + % This eucfont came from fixeucfont-1.2 by Mr. Norio Katayama + % (katayama@rd.nacsis.ac.jp). Thank you :) + % Modified: Feb 10 1999 for hankaku kana support. + % Special thanks to Mr. Toyohisa Kameyama (kameyama@sra.co.jp). + + /CIDeucfont { + /KanaFont exch dup type /nametype eq { findfont } if def + userdict /fixeucfont_dict known not { + userdict begin + /fixeucfont_dict 2 dict begin + /UpperByteEncoding [ + 16#00 1 16#0D { pop 0 } for + 78 % 0x0e SS2 kanaFont map. adding to last of basefont vector. + 16#0f 1 16#20 { pop 0 } for + 16#21 1 16#28 { 16#20 sub } for + 16#29 1 16#2F { pop 0 } for + 16#30 1 16#74 { 16#27 sub } for + 16#75 1 16#FF { pop 0 } for + ] def + /LowerByteEncoding [ + 16#00 1 16#A0 { pop /.notdef } for + 16#A1 1 16#FE { 16#80 sub 16 2 string cvrs + (cXX) dup 1 4 -1 roll + putinterval cvn } for + /.notdef + ] def + currentdict + end def + end + } if + 12 dict begin + dup type /nametype eq { findfont } if + dup /WMode known { + dup /WMode get /WMode exch def + WMode 1 eq { + [0.0 1.0 -1.0 0.0 0.0 0.30] makefont + } if + } if + % + % 7+8 bit EUC font + % + 12 dict begin + /EUCFont exch def + /FontInfo (7+8 bit EUC font) readonly def + /PaintType 0 def + /FontType 0 def + /FontMatrix matrix def + % /FontName + /Encoding fixeucfont_dict /UpperByteEncoding get def + /FMapType 2 def + EUCFont /WMode known + { EUCFont /WMode get /WMode exch def } + { /WMode 0 def } ifelse + /FDepVector [ + EUCFont /FDepVector get 0 get + [ 16#21 1 16#28 {} for 16#30 1 16#74 {} for ] + { + 13 dict begin + /EUCFont EUCFont def + /UpperByte exch 16#80 add def + % /FontName + /FontInfo (EUC lower byte font) readonly def + /PaintType 0 def + /FontType 3 def + /FontMatrix matrix def + /FontBBox {0 0 0 0} def + /Encoding fixeucfont_dict /LowerByteEncoding get def + % /UniqueID + % /WMode + /BuildChar { + gsave + exch dup /EUCFont get setfont + /UpperByte get + 2 string + dup 0 4 -1 roll put + dup 1 4 -1 roll put + dup stringwidth setcharwidth + 0 0 moveto show + grestore + } bind def + currentdict + end + /lowerbytefont exch definefont + } forall + KanaFont + ] def + currentdict + end + /kanjifont exch definefont + exch + + dup type /nametype eq { findfont } if + exch + + /FDepVector [ 4 2 roll ] def + /FontType 0 def + /FMapType 4 def + /FontMatrix matrix def + /Encoding [ 0 1 ] def + /FontBBox {0 0 0 0} def + dup /FontName exch def + currentdict + end + definefont pop + } def + + /eucfont { + 3 index FontDirectory exch known not { + CIDeucfont + } { pop pop pop pop } ifelse + } def %%EndProlog diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/tk.tcl ./library/tk.tcl *** ../../tk8.0.5/library/tk.tcl Tue Jan 5 04:25:27 1999 --- ./library/tk.tcl Sat Apr 10 05:07:01 1999 *************** *** 190,193 **** --- 190,321 ---- $w icur end } focus $w + } + + + # For Japanese text input and font definition. + + proc mkOptionFont {} { + set def [option get . tkDefineFont *] + if {[string length $def] == 0} { + return + } + set def [split $def ","] + foreach i $def { + set name [lindex $i 0] + set fonts [lindex $i 1] + catch {font create $name -compound $fonts} + } + + set def [option get . tkDefaultFont *] + if {[string length $def] == 0} { + return + } + set c "" + catch {set c [font conf $def -compound]} + if {[string length $c] > 0} { + option add *font $def userDefault + } + } + + + if {[string compare [info commands kanji] kanji] == 0} { + set isUnix 0 + if {[string compare $tcl_platform(platform) "unix"] == 0} { + set isUnix 1 + } + set src "" + set haveKinput 0 + if {$isUnix && [string compare [info commands kanjiInput] kanjiInput] == 0} { + set haveKinput 1 + } + set haveXIM 0 + if {[string compare [info commands imconfigure] imconfigure] == 0} { + set haveXIM 1 + } + if {$haveKinput == 1 && $haveXIM == 0} { + set src kinput.tcl + } elseif {$haveKinput == 0 && $haveXIM == 1} { + set src xim.tcl + } elseif {$haveKinput == 1 && $haveXIM == 1} { + if {$isUnix == 1} { + global env + set TK_KCPROTO "" + catch {set TK_KCPROTO [string tolower [lindex $env(TK_KCPROTO) 0]]} + if {[string length $TK_KCPROTO] <= 0} { + set TK_KCPROTO [string tolower [lindex [option get . tkKanjiConversionProtocol *] 0]] + } + if {[string length $TK_KCPROTO] > 0} { + switch "$TK_KCPROTO" { + "kinput" { + set src kinput.tcl + set haveXIM 0 + } + "kinput2" { + set src kinput.tcl + set haveXIM 0 + } + "xim" { + set src xim.tcl + set haveKinput 0 + } + } + } + if {[string length $src] == 0} { + set XMODIFIERS "" + catch {set XMODIFIERS $env(XMODIFIERS)} + if {[string length $XMODIFIERS] > 0} { + set src xim.tcl + set haveKinput 0 + } + } + if {[string length $src] == 0} { + set src kinput.tcl + set haveXIM 0 + } + if {$haveKinput == 0} { + if {[string compare [info commands kanjiInput] "kanjiInput"] == 0} { + rename kanjiInput "" + } + } + if {$haveXIM == 0} { + if {[string compare [info commands imconfigure] "imconfigure"] == 0} { + rename imconfigure "" + } + } + } + } + if {[string length $src] > 0} { + source [file join $tk_library $src] + } + + if {$isUnix == 0} { + if {[string compare $tcl_platform(platform) "macintosh"] == 0} { + toplevel .x + set str "Hi, Mac user, I think you are trying to compile Tk $tk_version japanized version on your machine. You hacker, I like it :) If you need any help about Tk's japanization, feel free to e-mail: + + tcl-jp-bugs@sra.co.jp + + Anyway, the first thing you have to do for japanization is: + + Shutting this stupid messages off :) + + Happy hacking!" + message .x.t -text $str + pack .x.t + bind .x.t <1> {destroy .x} + update + } + } + + if {[string length [info command kinsoku]] > 0} { + source [file join $tk_library kinsoku.tcl] + } + mkOptionFont + rename mkOptionFont "" + catch {unset isUnix} + catch {unset haveKinput} + catch {unset haveXIM} + catch {unset src} + catch {unset TK_KCPROTO} } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/library/xim.tcl ./library/xim.tcl *** ../../tk8.0.5/library/xim.tcl Thu Jan 1 09:00:00 1970 --- ./library/xim.tcl Mon May 10 19:10:19 1999 *************** *** 0 **** --- 1,888 ---- + if {[catch {set tkImPriv(debug)}]} { + set tkImPriv(debug) 0 + } + + proc tkGetPreferredIMInputStyle {prefStyle supportedStyle} { + foreach i $prefStyle { + if {[lsearch $supportedStyle $i] >= 0} { + return $i + } + } + return "" + } + + + proc tkGetIMInputStyle {path} { + global tkImPriv + set scrn [winfo screen $path] + + set sList "" + if {[catch {set sList $tkImPriv(imSupportedStyles:${scrn})}] == 1} { + catch {set sList [imconfigure $path -supportedStyle]} + set tkImPriv(imSupportedStyles:${scrn}) [lsort $sList] + } + if {[string length $sList] <= 0} { + puts stderr "Warning: No input method server is available." + return "" + } + + if {[catch {lappend s $tkImPriv(imPreferredStyles:$path)}] == 0} { + set s [tkGetPreferredIMInputStyle $s $sList] + if {[string length $s] > 0} { + return $s + } + } + + set style "" + set class [winfo class $path] + catch {set style $tkImPriv(imPreferredStyles:${class})} + if {[string length $style] > 0} { + if {[string compare "none" [lindex $style 0]] == 0} { + puts stderr "Warning: The input method server can't handle: [lindex $style 1]" + return "" + } else { + return $style + } + } else { + set userPref [option get . tkPreferredImStyle($class) *] + if {[string length $userPref] > 0} { + set style [tkGetPreferredIMInputStyle $userPref $sList] + if {[string length $style] > 0} { + set tkImPriv(imPreferredStyles:${class}) $style + return $style + } else { + set tkImPriv(imPreferredStyles:${class}) [list none $userPref] + puts stderr "Warning: The input method server can't handle style: {$userPref}" + return "" + } + } else { + switch "$class" { + "Text" { + set userPref [list "PreeditPosition StatusArea" "PreeditPosition StatusNothing" "PreeditArea StatusArea" "PreeditNothing StatusNothing"] + } + "Entry" { + set userPref [list "PreeditPosition StatusNothing" "PreeditNothing StatusNothing"] + } + "Canvas" { + set userPref [list "PreeditArea StatusArea" "PreeditNothing StatusNothing"] + } + default { + set userPref [list "PreeditPosition StatusArea" "PreeditPosition StatusNothing" "PreeditArea StatusArea" "PreeditNothing StatusNothing"] + } + } + set style [tkGetPreferredIMInputStyle $userPref $sList] + if {[string length $style] > 0} { + set tkImPriv(imPreferredStyles:${class}) $style + return $style + } else { + set tkImPriv(imPreferredStyles:${class}) [list none $userPref] + puts stderr "Warning: The input method server can't handle: {$userPref}" + return "" + } + } + } + return "" + } + + + proc tkCleanIMInputStyle {path} { + global tkImPriv + foreach i "imSupportedStyles:[winfo screen $path] imPreferredStyles:[winfo class $path] imPreferredStyles:${path}" { + catch {unset tkImPriv($i)} + } + } + + + # return 1 means "using on-the-spot". + proc tkConfigIm {path {force 0}} { + global tkImPriv + set stat "" + catch {set stat [imconfigure $path -status]} + if {[string length $stat] <= 0} { + tkCleanIMInputStyle $path + return 0 + } + set started 0 + if {$force == 1} { + set ret "imconfigure $path -force" + } else { + set ret "imconfigure $path" + } + set style "" + if {[string compare $stat "never"] == 0 || + [catch {set tkImPriv(imSetupDeleted:$path)}] == 0} { + catch {unset tkImPriv(imSetupDeleted:$path)} + set style [tkGetIMInputStyle $path] + if {[string length $style] <= 0} { + return 0 + } + append ret " -style {$style}" + } else { + set style [imconfigure $path -style] + set started 1 + } + + set preedit [lindex $style 0] + set status [lindex $style 1] + + if {[string compare $status "StatusCallbacks"] == 0 || + [string compare $preedit "PreeditCallbacks"] == 0} { + if {$started == 1} { + return 0 + } + append ret " -callback [tkGetIMCallbackProc $path]" + if {[catch {eval $ret} msg]} { + puts stderr "$msg" + return 0 + } else { + return 1 + } + } + + set fg "" + set bg "" + set font "" + set spot "" + set doStatusArea 0 + if {[string compare $status "StatusArea"] == 0} { + set doStatusArea 1 + } + + if {$tkImPriv(debug) == 0} { + if {[catch {set fg [$path cget -fg]}]} { + set fg black + } + if {[catch {set bg [$path cget -bg]}]} { + set bg white + } + } else { + set fg red + set bg blue + } + + if {[string compare $preedit "PreeditArea"] == 0 && $doStatusArea == 1} { + append ret " -foreground {$bg} -background {$fg}" + } else { + append ret " -foreground {$fg} -background {$bg}" + } + + set fontH 0 + if {[catch {set font [$path cget -font]}]} { + set font Mincho:Courier-12 + } else { + if {[string length $font] <= 0} { + set font Mincho:Courier-12 + } else { + set compound "" + catch {set compound [font conf $font -compound]} + if {[string length $compound] <= 0} { + set wFontH [expr [font metrics $font -ascent] + [font metrics $font -descent]] + set defFont [font failsafe] + if {[string length $defFont] > 0} { + set defFontH [expr [font metrics $defFont -ascent] + [font metrics $defFont -descent]] + if {$defFontH > $wFontH} { + set fontH $defFontH + } else { + set fontH $wFontH + } + } + } + } + } + append ret " -font {$font}" + + if {$started == 0} { + if {[catch {eval $ret} msg]} { + puts stderr "$msg" + return 0 + } + if {$force == 1} { + set ret "imconfigure $path -force" + } else { + set ret "imconfigure $path" + } + } + + set bo [expr [$path cget -bo] + [$path cget -highlightthickness]] + set w [expr [winfo width $path] - $bo * 2] + set h [expr [winfo height $path] - $bo * 2] + if {$fontH == 0} { + set fontH [expr [font metrics $font -ascent] + [font metrics $font -descent]] + } + set spotX $bo + set spotY $fontH + set stH $fontH + set stW [expr $fontH * 3] + if {$doStatusArea == 1} { + set spArea "" + catch {set spArea [imconfigure $path -preferredStatusArea]} + if {[string length $spArea] > 0} { + set pstW [lindex $spArea 2] + set pstH [lindex $spArea 3] + if {$pstW > 0 && $pstH > 0} { + if {[expr ${w}.0 / ${pstW}.0] <= 5.0} { + set pstW [expr $pstH * 3] + } + if {$stW < $pstW} { + set stW $pstW + } + if {$stH < $pstH} { + set stH $pstH + } + } + } + } + + switch "$preedit" { + "PreeditPosition" { + catch {set spot [$path xypos insert]} + if {[string length $spot] > 0} { + set spotX [lindex $spot 0] + set spotY [lindex $spot 1] + } + append ret " -spot {$spotX $spotY} -preeditArea {$bo $bo $w $h}" + if {$doStatusArea == 1} { + set stY [expr $spotY + $bo] + append ret " -statusArea {$spotX $stY $stW $stH}" + } + } + + "PreeditArea" { + switch "$status" { + "StatusNothing" { + append ret " -preeditArea {$bo $bo $w $h}" + } + "StatusArea" { + set H [expr $h - $stH + $bo] + set pX [expr $bo + $stW] + set pW [expr $w - $pX + $bo] + append ret " -preeditArea {$pX $H $pW $stH} -statusArea {$bo $H $stW $stH}" + } + } + } + } + if {[catch {eval $ret} msg]} { + puts stderr $msg + } + return 0 + } + + + # tkEntryBackspace -- redefine. + # Backspace over the character just before the insertion cursor. + # If backspacing would move the cursor off the left edge of the + # window, reposition the cursor at about the middle of the window. + # + # Arguments: + # w - The entry window in which to backspace. + + proc tkEntryBackspace w { + if {[$w selection present]} { + $w delete sel.first sel.last + } else { + set x [expr {[$w index insert] - 1}] + if {$x >= 0} {$w delete $x} + if {[$w index @0] >= [$w index insert]} { + set range [$w xview] + set left [lindex $range 0] + set right [lindex $range 1] + $w xview moveto [expr {$left - ($right - $left)/2.0}] + } + } + tkEntrySeeInsert $w + } + + + # tkEntrySeeInsert -- redefine. + # Make sure that the insertion cursor is visible in the entry window. + # If not, adjust the view so that it is. + # + # Arguments: + # w - The entry window. + + proc tkEntrySeeInsert w { + global tkImPriv + set useOnTheSpot [catch {set tkImPriv(useOnTheSpot:$w)}] + set c [$w index insert] + set left [$w index @0] + if {$left > $c} { + $w xview $c + if {$useOnTheSpot == 0} { + tkConfigIm $w + } + return + } + set x [winfo width $w] + while {([$w index @$x] <= $c) && ($left < $c)} { + incr left + $w xview $left + } + if {$useOnTheSpot == 0} { + tkConfigIm $w + } + } + + + # tkTextInsert -- redefine. + # Insert a string into a text at the point of the insertion cursor. + # If there is a selection in the text, and it covers the point of the + # insertion cursor, then delete the selection before inserting. + # + # Arguments: + # w - The text window in which to insert the string + # s - The string to insert (usually just a single character) + + proc tkTextInsert {w s} { + if {($s == "") || ([$w cget -state] == "disabled")} { + return + } + catch { + if {[$w compare sel.first <= insert] + && [$w compare sel.last >= insert]} { + $w delete sel.first sel.last + } + } + $w insert insert $s + $w see insert + global tkImPriv + if {[catch {set tkImPriv(useOnTheSpot:$w)}]} { + tkConfigIm $w + } + } + + + # tkTextSetCursor - redefine. + # Move the insertion cursor to a given position in a text. Also + # clears the selection, if there is one in the text, and makes sure + # that the insertion cursor is visible. Also, don't let the insertion + # cursor appear on the dummy last line of the text. + # + # Arguments: + # w - The text window. + # pos - The desired new position for the cursor in the window. + + proc tkTextSetCursor {w pos} { + if [$w compare $pos == end] { + set pos {end - 1 chars} + } + $w mark set insert $pos + $w tag remove sel 1.0 end + $w see insert + global tkImPriv + if {[catch {set tkImPriv(useOnTheSpot:$w)}]} { + tkConfigIm $w + } + } + + bind Text <1> { + tkTextButton1 %W %x %y + %W tag remove sel 0.0 end + tkTextSetCursor %W insert + } + + bind Text { + if {[%W tag nextrange sel 1.0 end] != ""} { + %W delete sel.first sel.last + tkTextSetCursor %W insert + } else { + tkTextSetCursor %W insert-1c + %W delete insert + %W see insert + } + } + + bind Text { + if {[%W tag nextrange sel 1.0 end] != ""} { + %W delete sel.first sel.last + tkTextSetCursor %W insert + } else { + tkTextSetCursor %W insert-1c + %W delete insert + %W see insert + } + } + + bind Text { + if {[%W tag nextrange sel 1.0 end] != ""} { + %W delete sel.first sel.last + tkTextSetCursor %W insert + } else { + tkTextSetCursor %W insert-1c + %W delete insert + %W see insert + } + } + + bind Text { + tkTextInsert %W \n + tkTextSetCursor %W insert + } + + + # on-the-spot + bind IMOnTheSpotTag { + global tkImPriv + tkDestroyIMStatusArea %W + catch {unset tkImPriv(imPreedit:%W:inConv)} + } + + + proc tkGetIMStatusGeometry {path} { + global tkImPriv + set sTop "" + catch {set sTop $tkImPriv(imStatusTop:${path})} + if {[string length $sTop] <= 0} { + return + } + set sW [winfo reqw $sTop] + set sH [winfo reqh $sTop] + set maxX [expr [winfo screenwidth .] - $sW] + set maxY [expr [winfo screenheight .] - $sH] + set X [expr [winfo rootx $path] - $sW] + set Y [expr [winfo rooty $path] - $sH + [winfo reqh $path]] + if {$X < 0} { + set X 0 + } + if {$Y < 0} { + set Y 0 + } + if {$X > $maxX} { + set X $maxX + } + if {$Y > $maxY} { + set Y $maxY + } + return "+${X}+${Y}" + } + + + proc tkGetPathOptionForIMStatusArea {path} { + set fg "" + set bg "" + set font "" + catch {set fg "-foreground [$path cget -foreground]"} + catch {set bg "-background [$path cget -background]"} + catch {set font "-font [$path cget -font]"} + return "$fg $bg $font" + } + + + proc tkDestroyIMStatusArea {path} { + global tkImPriv + set sTop "" + catch {set sTop $tkImPriv(imStatusTop:${path})} + if {[string length $sTop] <= 0} { + return + } + if {[winfo exists $sTop] == 1} { + destroy $sTop + } + catch {unset tkImPriv(imStatusTop:${path})} + } + + + proc tkCreateIMStatusArea {path} { + global tkImPriv + set sTop "" + catch {set sTop $tkImPriv(imStatusTop:${path})} + if {[string length $sTop] > 0} { + if {[winfo exists $sTop] == 1} { + return + } + } else { + regsub -all {\.} $path {_} eName + set sTop [toplevel ._imStatusArea_Of${eName} -bo 0 -highlightthickness 0] + wm withdraw $sTop + wm overrideredirect $sTop 1 + wm title $sTop "" + wm geometry $sTop +0+0 + eval "label ${sTop}.l [tkGetPathOptionForIMStatusArea $path] -text {}" + pack ${sTop}.l -padx 0 -pady 0 -expand false -fill none + set tkImPriv(imStatusTop:${path}) $sTop + set bTags [bindtags $path] + if {[lsearch -exact $bTags "IMOnTheSpotTag"] < 0} { + append bTags " IMOnTheSpotTag" + bindtags $path $bTags + } + return $sTop + } + } + + + proc tkMapIMStatusArea {path text {usesaved 0}} { + global tkImPriv + set sTop "" + catch {set sTop $tkImPriv(imStatusTop:${path})} + if {[string length $sTop] <= 0} { + set sTop [tkCreateIMStatusArea $path] + } + if {[string compare {[--]} $text] == 0 || + [string length $text] <= 0} { + set oText [${sTop}.l cget -text] + if {[string length $oText] <= 0} { + wm withdraw ${sTop} + ${sTop}.l configure -text "" + return + } + } + eval "${sTop}.l configure [tkGetPathOptionForIMStatusArea $path] -text {$text} -border 1 -rel raised" + update idletasks + wm geom ${sTop} [tkGetIMStatusGeometry $path] + if {![winfo ismapped ${sTop}]} { + wm deiconify ${sTop} + raise ${sTop} $path + } + } + + + proc tkUnmapIMStatusArea {path} { + global tkImPriv + set sTop "" + catch {set sTop $tkImPriv(imStatusTop:${path})} + if {[string length $sTop] <= 0} { + return + } + if {[winfo ismapped $sTop]} { + wm withdraw $sTop + } else { + ${sTop}.l configure -text "" + } + } + + + proc tkTextIMPreeditStart {path} { + global tkImPriv + set tkImPriv(imPreedit:${path}:first) [$path index insert] + catch {unset tkImPriv(imPreedit:${path}:tags)} + set tkImPriv(imPreedit:${path}:inConv) 0 + set tkImPriv(imPreedit:${path}:tagID) 0 + catch {unset tkImPriv(imPreedit:${path}:feedback)} + } + + + proc tkTextIMPreeditDone {path} { + global tkImPriv + catch {eval "$path tag delete $tkImPriv(imPreedit:${path}:tags)"} + catch {unset tkImPriv(imPreedit:${path}:first)} + catch {unset tkImPriv(imPreedit:${path}:tags)} + catch {unset tkImPriv(imPreedit:${path}:tagID)} + catch {unset tkImPriv(imPreedit:${path}:feedback)} + + set tkImPriv(imPreedit:${path}:inConv) 0 + } + + + proc tkGetTagOptionsFromIMTextStyle {path style} { + set ret "" + regsub -all {Primary} $style Reverse style + regsub -all {Secondary} $style Underline style + regsub -all {Tertiary} $style Highlight style + foreach i $style { + switch $i { + "Reverse" { + set fg [$path cget -foreground] + set bg [$path cget -background] + append ret "-foreground $bg -background $fg " + } + "Underline" { + append ret "-underline true " + } + "Highlight" { + append ret "-fgstipple gray75 " + } + default { + } + } + } + return $ret + } + + + proc tkTextInsertIMText {path imText} { + global tkImPriv + set orgPos "" + catch {set orgPos $tkImPriv(imPreedit:${path}:first)} + if {[string length $orgPos] <= 0} { + tkTextIMPreeditStart $path + catch {set orgPos $tkImPriv(imPreedit:${path}:first)} + if {[string length $orgPos] <= 0} { + return + } + } + if {[string length $imText] <= 0} { + return + } + set caret [lindex $imText 0] + set first [lindex $imText 1] + set len [lindex $imText 2] + set str [lindex $imText 3] + set sLen [kstring length $str] + set mode [lindex $imText 4] + + set cIdx "$orgPos + $caret char" + set sIdx "$orgPos + $first char" + set eIdx "$orgPos + [expr $first + $len] char" + $path delete $sIdx $eIdx + $path insert $sIdx $str + $path mark set insert $cIdx + + # incr tkImPriv(imPreedit:${path}:len) [expr -${len} +${sLen}] + # set tkImPriv(imPreedit:${path}:str) [$path get $orgPos [$path index "$orgPos + $tkImPriv(imPreedit:${path}:len) char"]] + # puts "debug: org $orgPos, end $eIdx, caret $cIdx, maxlen $tkImPriv(imPreedit:${path}:len) str $tkImPriv(imPreedit:${path}:str)" + + if {$sLen <= 0} { + if {$caret == 0 && $first == 0} { + tkTextIMPreeditDone $path + } + return + } + + if {$tkImPriv(imPreedit:${path}:inConv) == 0} { + set oMode "" + catch {set oMode $tkImPriv(imPreedit:${path}:feedback)} + if {[string length $oMode] <= 0} { + set oMode $mode + } + set tkImPriv(imPreedit:${path}:feedback) $mode + if {[string compare $mode $oMode] != 0} { + set tkImPriv(imPreedit:${path}:inConv) 1 + } + } else { + catch {eval "$path tag delete $tkImPriv(imPreedit:${path}:tags)"} + unset tkImPriv(imPreedit:${path}:tags) + set tkImPriv(imPreedit:${path}:tagID) 0 + } + + set opt [tkGetTagOptionsFromIMTextStyle $path $mode] + if {[string length $opt] > 0} { + set tag imTag$tkImPriv(imPreedit:${path}:tagID) + incr tkImPriv(imPreedit:${path}:tagID) + $path tag add $tag $sIdx "$sIdx + $sLen char" + lappend tkImPriv(imPreedit:${path}:tags) $tag + eval "$path tag configure $tag $opt" + } + } + + + proc tkTextMoveIMCaret {path pos cmd} { + global tkImPriv + catch {set orgPos $tkImPriv(imPreedit:${path}:first)} + if {[string length $orgPos] <= 0} { + tkTextIMPreeditStart $path + catch {set orgPos $tkImPriv(imPreedit:${path}:first)} + if {[string length $orgPos] <= 0} { + return + } + } + # Only AbsolutePosition is supported rite now. + + set cIdx "" + switch $cmd { + "AbsolutePosition" { + set cIdx [$path index "$orgPos + $pos char"] + } + } + if {[string length $cIdx] > 0} { + $path mark set insert $cIdx + } + } + + + proc tkGetIMCallbackProc {path} { + global tkImPriv + set ret "" + catch {set ret $tkImPriv(imOnTheSpotCallback:$path)} + if {[string length $ret] > 0} { + return $ret + } else { + set class [winfo class $path] + catch {set ret $tkImPriv(imOnTheSpotCallback:$class)} + if {[string length $ret] > 0} { + return $ret + } + } + return tkDummyIMCallbackProc + } + + + proc tkDummyIMCallbackProc {path class cmd {args ""}} { + global tkImPriv + if {$tkImPriv(debug) == 1} { + puts stderr "tkDummyIMCallbackProc $path $class $cmd '$args'" + } + if {[string compare $cmd "PreeditStart"] == 0} { + return -1 + } + return "" + } + + + proc tkTextIMCallbackProc {path class cmd {args ""}} { + global tkImPriv + if {$tkImPriv(debug) == 1} { + puts stderr "tkTextIMCallbackProc $path $class $cmd '$args'" + } + switch $cmd { + "PreeditStart" { + return -1 + } + "PreeditDone" { + tkTextIMPreeditDone $path + } + "PreeditDraw" { + tkTextInsertIMText $path $args + } + "PreeditCaret" { + tkTextMoveIMCaret $path [lindex $args 0] [lindex $args 1] + } + + "StatusStart" { + tkMapIMStatusArea $path "" 1 + } + "StatusDone" { + tkUnmapIMStatusArea $path + } + "StatusDraw" { + switch [lindex $args 0] { + "text" { + set str [lindex $args 1] + if {[string length $str] <= 0 || + [llength $str] <= 0} { + tkUnmapIMStatusArea $path + } else { + tkMapIMStatusArea $path $str + } + } + "bitmap" { + tkMapIMStatusArea $path [lindex $args 1] + } + } + } + } + } + + + # im bind. + bind imConfig { + global tkImPriv + if {[string compare [focus] "%W"] == 0 && + [catch {set tkImPriv(useOnTheSpot:%W)}]} { + tkConfigIm %W 1 + } + } + bind imConfig { + global tkImPriv + catch {unset tkImPriv(haveConfigHandler:%W)} + catch {unset tkImPriv(imOnTheSpotCallback:%W)} + catch {unset tkImPriv(useOnTheSpot:%W)} + catch {unset tkImPriv(imPreferredStyles:%W)} + catch {unset tkImPriv(imSetupDeleted:%W)} + } + + proc tkAddConfigImHandler {path} { + set tags [bindtags $path] + if {[lsearch $tags imConfig] < 0} { + bindtags $path "$tags imConfig" + } + } + + proc tkDeleteConfigImHandler {path} { + set tags [bindtags $path] + if {[lsearch $tags imConfig] >= 0} { + regsub -all imConfig $tags "" tags + bindtags $path $tags + } + } + + + proc tkInitializeIm {path} { + global tkImPriv + if {[catch {set tkImPriv(useOnTheSpot:$path)}] == 0} { + return + } + if {[tkConfigIm $path] == 1} { + set tkImPriv(useOnTheSpot:$path) 1 + } + if {[catch {set tkImPriv(haveConfigHandler:$path)}]} { + set tkImPriv(haveConfigHandler:$path) 1 + tkAddConfigImHandler $path + } + } + + + proc tkSetupIm {tags {style ""} {otsCallback ""}} { + set tags [string trimleft $tags] + set tags [string trimright $tags] + global tkImPriv + if {[string length $otsCallback] > 0} { + set tkImPriv(imOnTheSpotCallback:$tags) $otsCallback + } + if {[string length $style] > 0} { + set tkImPriv(imPreferredStyles:$tags) $style + } + set needBind 1 + set bTags "" + if {[string compare [string index $tags 0] "."] == 0} { + if {[winfo exists $tags]} { + set bTags [bindtags $tags] + } else { + set bTags $tags + } + } else { + set bTags $tags + } + foreach i $bTags { + set focusCmd [bind $i ] + if {[string length $focusCmd] > 0} { + if {[string first tkInitializeIm $focusCmd] >= 0} { + set needBind 0 + break + } + } + } + if {$needBind == 0} { + return + } + + bind $tags {tkInitializeIm %W} + } + + + proc tkCleanIm {tags} { + global tkImPriv + catch {unset tkImPriv(haveConfigHandler:%W)} + catch {unset tkImPriv(imOnTheSpotCallback:%W)} + catch {unset tkImPriv(useOnTheSpot:%W)} + catch {unset tkImPriv(imPreferredStyles:%W)} + tkDeleteConfigImHandler $tags + + set isPath 0 + set bTags "" + if {[string compare [string index $tags 0] "."] == 0} { + if {[winfo exists $tags]} { + set isPath 1 + set bTags [bindtags $tags] + } else { + set bTags $tags + } + } else { + set bTags $tags + } + foreach i $bTags { + set focusCmd [bind $i ] + if {[string length $focusCmd] > 0} { + if {[string first tkInitializeIm $focusCmd] >= 0} { + bind $i {} + } + } + } + + if {$isPath == 1} { + set tkImPriv(imSetupDeleted:$tags) 1 + } + } + + + foreach i "Text Entry" { + tkSetupIm $i "" tkTextIMCallbackProc + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/all ./tests/all *** ../../tk8.0.5/tests/all Tue Dec 8 08:29:00 1998 --- ./tests/all Mon Mar 15 14:08:14 1999 *************** *** 73,77 **** cd $currentDir } ! catch {destroy .} ! exit --- 73,79 ---- cd $currentDir } ! if {[info commands console] == {}} { ! catch {destroy .} ! exit ! } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/canvText.test ./tests/canvText.test *** ../../tk8.0.5/tests/canvText.test Fri Oct 16 09:46:19 1998 --- ./tests/canvText.test Fri Mar 12 00:38:36 1999 *************** *** 464,469 **** --- 464,476 ---- selection get } {fghi} + if {[string compare $tcl_platform(platform) "windows"] == 0} { + set kanjifont GothicBBB-Medium-EUC-H + set kanafont GothicBBB-Medium.Hankaku + } else { + set kanjifont Ryumin-Light-EUC-H + set kanafont Ryumin-Light.Hankaku + } set font {Courier 12 italic} set ax [font measure $font 0] set ay [font metrics $font -linespace] *************** *** 476,493 **** .c itemconfig test -font $font -text "00000000" -width [expr 3*$ax] .c itemconfig test -anchor n -fill black set x [.c postscript] ! set x [string range $x [string first "/Courier-Oblique" $x] end] ! } "/Courier-Oblique findfont [font actual $font -size] scalefont ISOEncode setfont 0.000 0.000 0.000 setrgbcolor AdjustColor 100 200 \[ (000) (000) (00) ! ] $ay -0.5 0 0 false DrawText grestore restore showpage %%Trailer end %%EOF ! " --- 483,518 ---- .c itemconfig test -font $font -text "00000000" -width [expr 3*$ax] .c itemconfig test -anchor n -fill black set x [.c postscript] ! if {[string length [info command kanji]] == 0} { ! set x [string range $x [string first "/Courier-Oblique" $x] end] ! } else { ! set x [string range $x [string first "(Courier 12 italic)" $x] end] ! } ! } [jp&orig "($font) cvn /Courier-Oblique /$kanjifont /$kanafont eucfont ! ($font) cvn findfont [font actual $font -size] scalefont setfont ! 0.000 0.000 0.000 setrgbcolor AdjustColor ! 100 200 \[ ! (000) ! (000) ! (00) ! \] $ay -0.5 0 0 false DrawText ! grestore ! restore showpage ! ! %%Trailer ! end ! %%EOF ! " "/Courier-Oblique findfont [font actual $font -size] scalefont ISOEncode setfont 0.000 0.000 0.000 setrgbcolor AdjustColor 100 200 \[ (000) (000) (00) ! \] $ay -0.5 0 0 false DrawText grestore restore showpage %%Trailer end %%EOF ! "] diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/defs ./tests/defs *** ../../tk8.0.5/tests/defs Fri Dec 4 13:19:12 1998 --- ./tests/defs Fri Mar 12 00:38:39 1999 *************** *** 323,328 **** --- 323,339 ---- set bgDone 1 } else { append bgData $x + } + } + + # Japanized version of Tcl might cause some errors. + # Followings are to avoid such kind of non-essential errors. + + proc jp&orig {jp orig} { + if { [ string length [ info commands kanji ] ] <= 0 } { + return $orig + } else { + return $jp } } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/entry.test ./tests/entry.test *** ../../tk8.0.5/tests/entry.test Tue Sep 15 03:23:45 1998 --- ./tests/entry.test Fri Mar 12 00:38:40 1999 *************** *** 229,235 **** } {4} test entry-3.26 {EntryWidgetCmd procedure, "index" widget command} { list [catch {.e in} msg] $msg ! } {1 {bad option "in": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, or xview}} test entry-3.27 {EntryWidgetCmd procedure, "index" widget command} { list [catch {.e index} msg] $msg } {1 {wrong # args: should be ".e index string"}} --- 229,237 ---- } {4} test entry-3.26 {EntryWidgetCmd procedure, "index" widget command} { list [catch {.e in} msg] $msg ! } [ jp&orig \ ! {1 {bad option "in": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, xview, or xypos}} \ ! {1 {bad option "in": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, or xview}} ] test entry-3.27 {EntryWidgetCmd procedure, "index" widget command} { list [catch {.e index} msg] $msg } {1 {wrong # args: should be ".e index string"}} *************** *** 458,464 **** } {73} test entry-3.75 {EntryWidgetCmd procedure} { list [catch {.e gorp} msg] $msg ! } {1 {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, or xview}} # The test below doesn't actually check anything directly, but if run # with Purify or some other memory-allocation-checking program it will --- 460,468 ---- } {73} test entry-3.75 {EntryWidgetCmd procedure} { list [catch {.e gorp} msg] $msg ! } [ jp&orig \ ! {1 {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, xview, or xypos}} \ ! {1 {bad option "gorp": must be bbox, cget, configure, delete, get, icursor, index, insert, scan, selection, or xview}} ] # The test below doesn't actually check anything directly, but if run # with Purify or some other memory-allocation-checking program it will diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/font.test ./tests/font.test *** ../../tk8.0.5/tests/font.test Tue Sep 15 03:23:47 1998 --- ./tests/font.test Tue Apr 6 20:04:13 1999 *************** *** 12,23 **** if {[string compare test [info procs test]] != 0} { source defs } ! catch {destroy .b} toplevel .b wm geom .b +0+0 update idletasks proc setup {} { catch {destroy .b.f} catch {font delete xyz} --- 12,35 ---- if {[string compare test [info procs test]] != 0} { source defs } ! if {[string compare kanji [info command kanji]] == 0} { ! font cache clear ! } catch {destroy .b} toplevel .b wm geom .b +0+0 update idletasks + catch {unset fontnames} + catch {unset charset} + if {[string compare $tcl_platform(platform) "windows"] == 0} { + set fontnames {} + set charset(a) default + } else { + set fontnames {Mincho:Courier-12 Mincho:Helvetica-12 Mincho:Helvetica-Bold-12} + set charset(a) iso8859 + } + proc setup {} { catch {destroy .b.f} catch {font delete xyz} *************** *** 76,82 **** } {0} test font-1.7 {font command: actual: displayof specified, so skip to next} { lindex [font actual xyz -displayof .] 0 ! } {-family} test font-1.8 {font command: actual} {unix || mac} { string tolower [font actual {-family times} -family] } {times} --- 88,94 ---- } {0} test font-1.7 {font command: actual: displayof specified, so skip to next} { lindex [font actual xyz -displayof .] 0 ! } [jp&orig {-foundry} {-family}] test font-1.8 {font command: actual} {unix || mac} { string tolower [font actual {-family times} -family] } {times} *************** *** 85,95 **** } {Times New Roman} test font-1.10 {font command: actual} { lindex [font actual {-family times}] 0 ! } {-family} test font-1.11 {font command: bad option} { list [catch {font actual xyz -style} msg] $msg ! } {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ! test font-2.1 {font command: configure} { list [catch {font configure} msg] $msg } {1 {wrong # args: should be "font configure fontname ?options?"}} --- 97,108 ---- } {Times New Roman} test font-1.10 {font command: actual} { lindex [font actual {-family times}] 0 ! } [jp&orig {-foundry} {-family}] test font-1.11 {font command: bad option} { list [catch {font actual xyz -style} msg] $msg ! } [ jp&orig \ ! {1 {bad option "-style": must be -foundry, -family, -size, -weight, -slant, -underline, -overstrike, -charset, -pointadjust, or -compound}} \ ! {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ] test font-2.1 {font command: configure} { list [catch {font configure} msg] $msg } {1 {wrong # args: should be "font configure fontname ?options?"}} *************** *** 106,112 **** test font-2.4 {font command: configure: get all options} { setup font create xyz -family xyz ! lindex [font configure xyz] 1 } xyz test font-2.5 {font command: configure: get one option} { setup --- 119,125 ---- test font-2.4 {font command: configure: get all options} { setup font create xyz -family xyz ! lindex [font configure xyz] [jp&orig 3 1] } xyz test font-2.5 {font command: configure: get one option} { setup *************** *** 124,130 **** setup font create xyz list [catch {font configure xyz -style} msg] $msg ! } {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}} test font-3.1 {font command: create: make up name} { font delete [font create] --- 137,145 ---- setup font create xyz list [catch {font configure xyz -style} msg] $msg ! } [ jp&orig \ ! {1 {bad option "-style": must be -foundry, -family, -size, -weight, -slant, -underline, -overstrike, -charset, -pointadjust, or -compound}} \ ! {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ] test font-3.1 {font command: create: make up name} { font delete [font create] *************** *** 141,147 **** .b.f configure -font xyz font delete xyz list [catch {font create xyz -xyz times} msg] $msg ! } {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}} test font-3.4 {font command: create: recreate "deleted" font} { setup font create xyz --- 156,164 ---- .b.f configure -font xyz font delete xyz list [catch {font create xyz -xyz times} msg] $msg ! } [ jp&orig \ ! {1 {bad option "-xyz": must be -foundry, -family, -size, -weight, -slant, -underline, -overstrike, -charset, -pointadjust, or -compound}} \ ! {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ] test font-3.4 {font command: create: recreate "deleted" font} { setup font create xyz *************** *** 155,161 **** test font-3.5 {font command: create: bad option creating new font} { setup list [catch {font create xyz -xyz times} msg] $msg ! } {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}} test font-3.6 {font command: create: totally new font} { setup font create xyz -family xyz --- 172,180 ---- test font-3.5 {font command: create: bad option creating new font} { setup list [catch {font create xyz -xyz times} msg] $msg ! } [ jp&orig \ ! {1 {bad option "-xyz": must be -foundry, -family, -size, -weight, -slant, -underline, -overstrike, -charset, -pointadjust, or -compound}} \ ! {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ] test font-3.6 {font command: create: totally new font} { setup font create xyz -family xyz *************** *** 270,276 **** font delete abc font delete xyz set x ! } {abc xyz} test font-8.3 {font command: names} { setup font create xyz --- 289,297 ---- font delete abc font delete xyz set x ! } [ jp&orig \ ! [concat $fontnames abc xyz] \ ! {abc xyz} ] test font-8.3 {font command: names} { setup font create xyz *************** *** 278,291 **** set x [lsort [font names]] .b.f config -font xyz font delete xyz ! lappend x [font names] font delete abc set x ! } {abc xyz abc} test font-9.1 {font command: unknown option} { list [catch {font xyz} msg] $msg ! } {1 {bad option "xyz": must be actual, configure, create, delete, families, measure, metrics, or names}} test font-10.1 {UpdateDependantFonts procedure: no users} { setup --- 299,316 ---- set x [lsort [font names]] .b.f config -font xyz font delete xyz ! lappend x [lsort [font names]] font delete abc set x ! } [ jp&orig \ ! [concat $fontnames abc xyz [list [concat $fontnames abc]]] \ ! {abc xyz abc} ] test font-9.1 {font command: unknown option} { list [catch {font xyz} msg] $msg ! } [ jp&orig \ ! {1 {bad option "xyz": must be actual, cache, configure, create, delete, failsafe, families, measure, metrics, names, or prefetch}} \ ! {1 {bad option "xyz": must be actual, configure, create, delete, families, measure, metrics, or names}} ] test font-10.1 {UpdateDependantFonts procedure: no users} { setup *************** *** 310,322 **** setup .b.f config -font {-family fixed} lindex [font actual {-family fixed}] 0 ! } {-family} test font-11.2 {Tk_GetFont procedure: bump ref count of named font, too} { setup font create xyz .b.f config -font xyz lindex [font actual xyz] 0 ! } {-family} test font-11.3 {Tk_GetFont procedure: get named font} { setup font create xyz --- 335,347 ---- setup .b.f config -font {-family fixed} lindex [font actual {-family fixed}] 0 ! } [jp&orig {-foundry} {-family}] test font-11.2 {Tk_GetFont procedure: bump ref count of named font, too} { setup font create xyz .b.f config -font xyz lindex [font actual xyz] 0 ! } [jp&orig {-foundry} {-family}] test font-11.3 {Tk_GetFont procedure: get named font} { setup font create xyz *************** *** 339,345 **** } {1 {expected integer but got "yyy"}} test font-11.8 {Tk_GetFont procedure: get attribute font} { lindex [font actual {plan 9}] 0 ! } {-family} test font-11.9 {Tk_GetFont procedure: no match} { list [catch {font actual {}} msg] $msg } {1 {font "" doesn't exist}} --- 364,370 ---- } {1 {expected integer but got "yyy"}} test font-11.8 {Tk_GetFont procedure: get attribute font} { lindex [font actual {plan 9}] 0 ! } [jp&orig {-foundry} {-family}] test font-11.9 {Tk_GetFont procedure: no match} { list [catch {font actual {}} msg] $msg } {1 {font "" doesn't exist}} *************** *** 369,376 **** font create xyz .b.f config -font xyz destroy .b.f ! font names ! } {xyz} test font-13.4 {Tk_FreeFont procedure: named font} { setup font create xyz -underline 1 --- 394,403 ---- font create xyz .b.f config -font xyz destroy .b.f ! lsort [ font names ] ! } [ jp&orig \ ! [concat $fontnames xyz] \ ! {xyz} ] test font-13.4 {Tk_FreeFont procedure: named font} { setup font create xyz -underline 1 *************** *** 389,395 **** set x [font actual xyz] destroy .b.b list [lindex [font actual xyz] 0] [lindex $x 0] ! } {-family -family} test font-14.1 {Tk_FontId} { .b.f config -font "times 20" --- 416,422 ---- set x [font actual xyz] destroy .b.b list [lindex [font actual xyz] 0] [lindex $x 0] ! } [jp&orig {-foundry -foundry} {-family -family}] test font-14.1 {Tk_FontId} { .b.f config -font "times 20" *************** *** 408,413 **** --- 435,454 ---- .b.c itemconfig text -font $name set post [.b.c postscript] .b.c itemconfig text -font $a + if {[string length [info command kanji]] > 0} { + set start [string first "%%Page:" $post] + set end [string last "end" $post] + set post [string range $post $start $end] + set end [string first "eucfont" $post] + set start [string first ") cvn" $post] + set post [string range $post $start $end] + set start [string first "/" $post] + incr start + set post [string range $post $start $end] + set end [string first "/" $post] + incr end -2 + return [string range $post 0 $end] + } set end [string first "findfont" $post] incr end -2 set post [string range $post [expr $end-70] $end] *************** *** 714,720 **** test font-22.11 {Tk_PointToChar procedure: below all chunks} { csetup "000 0000000" .b.c index text @0,1000000 ! } {11} test font-23.1 {Tk_CharBBox procedure: index < 0} { .b.f config -text "000" -underline -1 --- 755,761 ---- test font-22.11 {Tk_PointToChar procedure: below all chunks} { csetup "000 0000000" .b.c index text @0,1000000 ! } [ jp&orig {11} {10} ] test font-23.1 {Tk_CharBBox procedure: index < 0} { .b.f config -text "000" -underline -1 *************** *** 923,929 **** setup font create xyz font config xyz ! } {-family {} -size 0 -weight normal -slant roman -underline 0 -overstrike 0} test font-30.1 {ConfigAttributes procedure: arguments} { setup --- 964,972 ---- setup font create xyz font config xyz ! } [ jp&orig \ ! {-foundry {} -family {} -size 0 -weight normal -slant roman -underline 0 -overstrike 0 -charset {} -pointadjust 0 -compound {}} \ ! {-family {} -size 0 -weight normal -slant roman -underline 0 -overstrike 0} ] test font-30.1 {ConfigAttributes procedure: arguments} { setup *************** *** 932,938 **** test font-30.2 {ConfigAttributes procedure: arguments} { setup list [catch {font create xyz -xyz xyz} msg] $msg ! } {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}} set i 3 foreach p { {family xyz times} --- 975,983 ---- test font-30.2 {ConfigAttributes procedure: arguments} { setup list [catch {font create xyz -xyz xyz} msg] $msg ! } [ jp&orig \ ! {1 {bad option "-xyz": must be -foundry, -family, -size, -weight, -slant, -underline, -overstrike, -charset, -pointadjust, or -compound}} \ ! {1 {bad option "-xyz": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ] set i 3 foreach p { {family xyz times} *************** *** 969,980 **** test font-31.1 {GetAttributeInfo procedure: error} { list [catch {font actual xyz -style} msg] $msg ! } {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}} test font-31.2 {GetAttributeInfo procedure: all attributes} { setup font create xyz -family xyz font config xyz ! } {-family xyz -size 0 -weight normal -slant roman -underline 0 -overstrike 0} set i 3 foreach p { {family xyz xyz} --- 1014,1029 ---- test font-31.1 {GetAttributeInfo procedure: error} { list [catch {font actual xyz -style} msg] $msg ! } [ jp&orig \ ! {1 {bad option "-style": must be -foundry, -family, -size, -weight, -slant, -underline, -overstrike, -charset, -pointadjust, or -compound}} \ ! {1 {bad option "-style": must be -family, -size, -weight, -slant, -underline, or -overstrike}} ] test font-31.2 {GetAttributeInfo procedure: all attributes} { setup font create xyz -family xyz font config xyz ! } [ jp&orig \ ! {-foundry {} -family xyz -size 0 -weight normal -slant roman -underline 0 -overstrike 0 -charset {} -pointadjust 0 -compound {}} \ ! {-family xyz -size 0 -weight normal -slant roman -underline 0 -overstrike 0} ] set i 3 foreach p { {family xyz xyz} *************** *** 999,1017 **** setup test font-32.1 {ParseFontName procedure: begins with -} { ! lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1 } $times test font-32.2 {ParseFontName procedure: begins with -*} { ! lindex [font actual -*-times-xyz-*-*-*-*-*-*-*-*-*-*-*] 1 } $times test font-32.3 {ParseFontName procedure: begins with -, doesn't look like list} { ! lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1 } $times test font-32.4 {ParseFontName procedure: begins with -, looks like list} { ! lindex [font actual {-family times}] 1 } $times test font-32.5 {ParseFontName procedure: begins with *} { ! lindex [font actual *-times-xyz-*-*-*-*-*-*-*-*-*-*-*] 1 } $times test font-32.6 {ParseFontName procedure: begins with *} { font actual *-times-xyz -family --- 1048,1066 ---- setup test font-32.1 {ParseFontName procedure: begins with -} { ! lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] [jp&orig 3 1] } $times test font-32.2 {ParseFontName procedure: begins with -*} { ! lindex [font actual -*-times-xyz-*-*-*-*-*-*-*-*-*-*-*] [jp&orig 3 1] } $times test font-32.3 {ParseFontName procedure: begins with -, doesn't look like list} { ! lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] [jp&orig 3 1] } $times test font-32.4 {ParseFontName procedure: begins with -, looks like list} { ! lindex [font actual {-family times}] [jp&orig 3 1] } $times test font-32.5 {ParseFontName procedure: begins with *} { ! lindex [font actual *-times-xyz-*-*-*-*-*-*-*-*-*-*-*] [jp&orig 3 1] } $times test font-32.6 {ParseFontName procedure: begins with *} { font actual *-times-xyz -family *************** *** 1029,1036 **** lrange [font actual {times 12 bold italic overstrike underline}] 4 end } {-weight bold -slant italic -underline 1 -overstrike 0} test font-32.11 {ParseFontName procedure: stylelist loop} {unixOrPc} { ! lrange [font actual {times 12 bold italic overstrike underline}] 4 end ! } {-weight bold -slant italic -underline 1 -overstrike 1} test font-32.12 {ParseFontName procedure: stylelist error} { list [catch {font actual {times 12 bold xyz}} msg] $msg } {1 {unknown font style "xyz"}} --- 1078,1087 ---- lrange [font actual {times 12 bold italic overstrike underline}] 4 end } {-weight bold -slant italic -underline 1 -overstrike 0} test font-32.11 {ParseFontName procedure: stylelist loop} {unixOrPc} { ! lrange [font actual {times 12 bold italic overstrike underline}] [jp&orig 6 4] end ! } [ jp&orig \ ! [list -weight bold -slant italic -underline 1 -overstrike 1 -charset $charset(a) -pointadjust 0 -compound {}] \ ! {-weight bold -slant italic -underline 1 -overstrike 1} ] test font-32.12 {ParseFontName procedure: stylelist error} { list [catch {font actual {times 12 bold xyz}} msg] $msg } {1 {unknown font style "xyz"}} *************** *** 1046,1054 **** } $times test font-33.4 {TkParseXLFD procedure: all fields unspecified} { lindex [font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*] 0 ! } {-family} test font-33.5 {TkParseXLFD procedure: all fields specified} { ! lindex [font actual -foundry-times-weight-slant-setwidth-addstyle-10-10-10-10-spacing-avgwidth-registry-encoding] 1 } $times test font-33.6 {TkParseXLFD procedure: arguments} { # XLFD with bad pointsize: fallback to some system font. --- 1097,1105 ---- } $times test font-33.4 {TkParseXLFD procedure: all fields unspecified} { lindex [font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-*] 0 ! } [jp&orig {-foundry} {-family}] test font-33.5 {TkParseXLFD procedure: all fields specified} { ! lindex [font actual -foundry-times-weight-slant-setwidth-addstyle-10-10-10-10-spacing-avgwidth-registry-encoding] [jp&orig 3 1] } $times test font-33.6 {TkParseXLFD procedure: arguments} { # XLFD with bad pointsize: fallback to some system font. *************** *** 1081,1087 **** font actual -xyz--*-*-*-*-*-*-*-*-*-*-*-* font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-* font actual -xyz-?-*-*-*-*-*-*-*-*-*-*-*-* ! lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] 1 } $times test font-35.1 {NewChunk procedure: test realloc} { --- 1132,1138 ---- font actual -xyz--*-*-*-*-*-*-*-*-*-*-*-* font actual -xyz-*-*-*-*-*-*-*-*-*-*-*-*-* font actual -xyz-?-*-*-*-*-*-*-*-*-*-*-*-* ! lindex [font actual -xyz-times-*-*-*-*-*-*-*-*-*-*-*-*] [jp&orig 3 1] } $times test font-35.1 {NewChunk procedure: test realloc} { *************** *** 1089,1092 **** --- 1140,1148 ---- } {} destroy .b + if {[string compare kanji [info command kanji]] == 0} { + font cache clear + } + catch {unset fontnames} + catch {unset charset} return diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/fontjp.test ./tests/fontjp.test *** ../../tk8.0.5/tests/fontjp.test Thu Jan 1 09:00:00 1970 --- ./tests/fontjp.test Mon May 10 19:10:25 1999 *************** *** 0 **** --- 1,215 ---- + # Commands covered: compound font + # + # Copyright (c) 1993, 1999 Software Research Associates, Inc. + # Permission to use, copy, modify, and distribute this software and its + # documentation for any purpose and without fee is hereby granted, provided + # that the above copyright notice appear in all copies and that both that + # copyright notice and this permission notice appear in supporting + # documentation, and that the name of Software Research Associates not be + # used in advertising or publicity pertaining to distribution of the + # software without specific, written prior permission. Software Research + # Associates makes no representations about the suitability of this software + # for any purpose. It is provided "as is" without express or implied + # warranty. + # + # $Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/tests/fontjp.test,v 1.16 1999/04/24 06:42:14 m-hirano Exp $ + + if {[string compare test [info procs test]] != 0} { + source defs + } + + if {[string length [info command kanji]] <= 0} { + return + } + + catch {unset foundry} + catch {unset family} + catch {unset charset} + catch {unset failsafefont} + if {[string compare $tcl_platform(platform) "windows"] == 0} { + catch {font delete a14} + catch {font delete k14} + font create a14 -copy {{Courier New} 14} + font create k14 -copy defaultgui -size 14 + set foundry(a) {} + set foundry(k) {} + set foundry(c) {{}:{}} + set family(a) {Courier New} + set family(k) {$B#M#S(B $B#P%4%7%C%/(B} + set charset(a) default + set charset(k) shiftjis + set failsafefont(a) ansifixed + set failsafefont(k) defaultgui + } else { + set foundry(a) misc + set foundry(k) misc + set foundry(c) $foundry(a):$foundry(k) + set family(a) fixed + set family(k) fixed + set charset(a) iso8859 + set charset(k) jisx0208.1983 + set failsafefont(a) a14 + set failsafefont(k) k14 + } + + if {[string length [font names]] <= 0} { + return + } + + set fFont [font failsafe] + set prefetch [font prefetch] + font prefetch yes + + proc setup {} { + catch {destroy .b} + toplevel .b + wm geom .b +0+0 + update + catch {font delete @ascii} + catch {font delete @kanji} + catch {font delete @comp} + catch {font delete @aa} + catch {font delete @kk} + catch {font delete @res} + set txt "$B$*H$$N9q$+$i$3$s$K$A$O!#$3$l$O(B Tcl/Tk 8.0 $BF|K\8lHG$N%F%9%H$G$9!#(B\nGreeting from the chopsticks world. This is test for Tcl/Tk 8.0 Japanizaton." + label .b.l0 -text $txt -bo 1 -rel raised + label .b.l1 -text $txt -bo 1 -rel raised -bg blue -fg white + pack .b.l0 .b.l1 + update + font create @ascii -copy a14 + font create @kanji -copy k14 + font create @comp -compound {@ascii @kanji} + font create @aa -copy a14 + font create @kk -copy k14 + font create @res -compound {@aa @kk} + } + + proc cleanup {} { + catch {destroy .b} + catch {font delete @ascii} + catch {font delete @kanji} + catch {font delete @comp} + catch {font delete @aa} + catch {font delete @kk} + catch {font delete @res} + catch {font delete @kkk} + } + + setup + + test fontjp-1.1 {compound: configure} { + .b.l1 conf -font @comp + update + } {} + + test fontjp-1.2 {compound: resize} { + .b.l1 conf -font @res + font conf @res -size 16 + update + after 250 + } {} + + test fontjp-1.3 {compound: underline} { + font conf @res -underline 1 + update + after 250 + } {} + + test fontjp-1.4 {compound: overstrike} { + font conf @res -overstrike 1 -underline 0 + update + after 250 + } {} + #.b.l1 conf -font @comp + #update + + test fontjp-2.1 {failsafe: kanji} { + font failsafe $failsafefont(k) + .b.l1 conf -font {Courier -18} + update + after 250 + } {} + + test fontjp-2.2 {failsafe: ascii} { + font failsafe $failsafefont(a) + font create @kkk -copy k14 + .b.l1 conf -font @kkk + font conf @kkk -size 16 + update + after 250 + } {} + + test fontjp-2.3 {failsafe: ascii-ascii} { + .b.l1 conf -font {Courier -18} + update + after 250 + } {} + + test fontjp-2.4 {failsafe: kanji-kanji} { + font failsafe $failsafefont(k) + .b.l1 conf -font k14 + update + after 250 + } {} + + test fontjp-2.5 {failsafe: named font} { + list [catch {font failsafe @kkk} msg] $msg + } {1 {can't load font "@kkk".}} + + cleanup + + test fontjp-3.1 {compound: create with option} { + set f [font create @vvv -compound {a14 k14} -size 15 -underline 1] + font conf $f + } [list -foundry $foundry(c) -family $family(a):$family(k) -size 15 -weight normal -slant roman -underline 1 -overstrike 0 -charset $charset(a):$charset(k) -pointadjust 1.000000 -compound {{a14} {k14}}] + font delete @vvv + + proc doIt {str font} { + catch {destroy .t} + toplevel .t + wm geom .t +0+0 + pack [label .t.l -text $str -font $font] + update + } + + set str "resize $B%F%-%9%H(B" + for {set i 12; set j 0} {$i < 32} {incr i 2; incr j 1} { + catch {font delete @a} + catch {font delete @k} + catch {font delete @c} + font cache clear + font create @a -family $family(a) -weight normal -charset $charset(a) -size -14 + font create @k -family $family(k) -weight normal -charset $charset(k) -size -14 + font create @c -compound {@a @k} -size -$i -underline 1 + doIt $str @c + test fontjp-4.1.$j {compound: resize (igonre foundry)} { + list [font conf @a -family] [font conf @k -family] [font conf @c -family] + } [list $family(a) $family(k) $family(a):$family(k)] + } + + for {set i 12; set j 0} {$i < 32} {incr i 2; incr j 1} { + catch {font delete @a} + catch {font delete @k} + catch {font delete @c} + font cache clear + font create @a -copy a14 + font create @k -copy k14 + font create @c -compound {@a @k} -size $i -underline 1 + doIt $str @c + test fontjp-4.2.$j {compound: resize (using same font precisely)} { + list [font conf @a -foundry] [font conf @a -family] [font conf @k -foundry] [font conf @k -family] [font conf @c -foundry] [font conf @c -family] + } [list $foundry(a) $family(a) $foundry(k) $family(k) $foundry(c) $family(a):$family(k)] + } + + font prefetch $prefetch + unset str + catch {font delete @a} + catch {font delete @k} + catch {font delete @c} + catch {destroy .t} + catch {font failsafe $fFont} + catch {font cache clear} + catch {unset foundry} + catch {unset family} + catch {unset charset} + catch {unset failsafefont} diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/grid.test ./tests/grid.test *** ../../tk8.0.5/tests/grid.test Thu Jan 7 06:10:46 1999 --- ./tests/grid.test Fri Mar 12 00:38:43 1999 *************** *** 323,328 **** --- 323,329 ---- set a "" foreach i {0 1 2} { frame .$i -width 120 -height 75 -bg red + update lappend a [grid location . 150 90] grid .$i -row $i -column $i } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/select.test ./tests/select.test *** ../../tk8.0.5/tests/select.test Tue Sep 15 03:23:50 1998 --- ./tests/select.test Fri Mar 12 00:38:52 1999 *************** *** 135,141 **** selection handle .f1 {handler TEST} TEST selection handle .f1 {handler STRING} lsort [selection get TARGETS] ! } {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} test select-1.5 {Tk_CreateSelHandler procedure} { global selValue selInfo setup --- 135,143 ---- selection handle .f1 {handler TEST} TEST selection handle .f1 {handler STRING} lsort [selection get TARGETS] ! } [jp&orig \ ! {MULTIPLE TARGETS TEST TEXT TIMESTAMP TK_APPLICATION TK_WINDOW} \ ! {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}] test select-1.5 {Tk_CreateSelHandler procedure} { global selValue selInfo setup *************** *** 157,163 **** selection handle .f1 {handler TEST2} TEST selection get -type TEST list [set selInfo] [lsort [selection get TARGETS]] ! } {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}} test select-1.7 {Tk_CreateSelHandler procedure} { setup selection own -selection CLIPBOARD .f1 --- 159,167 ---- selection handle .f1 {handler TEST2} TEST selection get -type TEST list [set selInfo] [lsort [selection get TARGETS]] ! } [jp&orig \ ! {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE TARGETS TEST TEXT TIMESTAMP TK_APPLICATION TK_WINDOW}} \ ! {{STRING 0 4000 TEST 0 4000 TEST2 0 4000} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}] test select-1.7 {Tk_CreateSelHandler procedure} { setup selection own -selection CLIPBOARD .f1 *************** *** 182,188 **** set result [list [lsort [selection get TARGETS]]] selection handle -type TEST .f1 {} lappend result [lsort [selection get TARGETS]] ! } {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW USER}} test select-2.2 {Tk_DeleteSelHandler procedure} { setup selection handle .f1 {handler STRING} --- 186,194 ---- set result [list [lsort [selection get TARGETS]]] selection handle -type TEST .f1 {} lappend result [lsort [selection get TARGETS]] ! } [jp&orig \ ! {{MULTIPLE TARGETS TEST TEXT TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE TARGETS TEXT TIMESTAMP TK_APPLICATION TK_WINDOW USER}} \ ! {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW USER}}] test select-2.2 {Tk_DeleteSelHandler procedure} { setup selection handle .f1 {handler STRING} *************** *** 191,197 **** set result [list [lsort [selection get TARGETS]]] selection handle -type USER .f1 {} lappend result [lsort [selection get TARGETS]] ! } {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}} test select-2.3 {Tk_DeleteSelHandler procedure} { setup selection own -selection CLIPBOARD .f1 --- 197,205 ---- set result [list [lsort [selection get TARGETS]]] selection handle -type USER .f1 {} lappend result [lsort [selection get TARGETS]] ! } [jp&orig \ ! {{MULTIPLE TARGETS TEST TEXT TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE TARGETS TEST TEXT TIMESTAMP TK_APPLICATION TK_WINDOW}} \ ! {{MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW USER} {MULTIPLE STRING TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}] test select-2.3 {Tk_DeleteSelHandler procedure} { setup selection own -selection CLIPBOARD .f1 *************** *** 200,206 **** selection handle -selection CLIPBOARD .f1 {} list [lsort [selection get TARGETS]] \ [lsort [selection get -selection CLIPBOARD TARGETS]] ! } {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}} test select-2.4 {Tk_DeleteSelHandler procedure} { setup selection handle .f1 {handler STRING} --- 208,216 ---- selection handle -selection CLIPBOARD .f1 {} list [lsort [selection get TARGETS]] \ [lsort [selection get -selection CLIPBOARD TARGETS]] ! } [jp&orig \ ! {{MULTIPLE TARGETS TEXT TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}} \ ! {{MULTIPLE STRING TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}] test select-2.4 {Tk_DeleteSelHandler procedure} { setup selection handle .f1 {handler STRING} *************** *** 849,855 **** setupbg set selValue $longValue set selInfo "" ! selection handle .f1 {errIncrHandler STRING} set result "" set pass 0 lappend result [dobg {selection get}] --- 859,869 ---- setupbg set selValue $longValue set selInfo "" ! if {[string length [info command kanji]] > 0} { ! selection handle .f1 {errIncrHandler STRING} STRING ! } else { ! selection handle .f1 {errIncrHandler STRING} ! } set result "" set pass 0 lappend result [dobg {selection get}] *************** *** 872,877 **** --- 886,892 ---- proc weirdHandler {type offset count} { destroy .f1 handler $type $offset $count + update } setup setupbg *************** *** 975,981 **** setupbg set selValue $longValue set selInfo "" ! selection handle .f1 {badHandler .f1 STRING} set result "" set abortCount 2 lappend result [dobg {selection get}] --- 990,1000 ---- setupbg set selValue $longValue set selInfo "" ! if {[string length [info command kanji]] > 0} { ! selection handle .f1 {badHandler .f1 STRING} STRING ! } else { ! selection handle .f1 {badHandler .f1 STRING} ! } set result "" set abortCount 2 lappend result [dobg {selection get}] diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/text.test ./tests/text.test *** ../../tk8.0.5/tests/text.test Tue Sep 15 03:23:50 1998 --- ./tests/text.test Fri Mar 12 00:38:53 1999 *************** *** 150,156 **** } {1 {wrong # args: should be ".t option ?arg arg ...?"}} test text-3.2 {TextWidgetCmd procedure} { list [catch {.t gorp 1.0 z 1.2} msg] $msg ! } {1 {bad option "gorp": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} test text-4.1 {TextWidgetCmd procedure, "bbox" option} { list [catch {.t bbox} msg] $msg --- 150,158 ---- } {1 {wrong # args: should be ".t option ?arg arg ...?"}} test text-3.2 {TextWidgetCmd procedure} { list [catch {.t gorp 1.0 z 1.2} msg] $msg ! } [ jp&orig \ ! {1 {bad option "gorp": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, xypos, or yview}} \ ! {1 {bad option "gorp": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} ] test text-4.1 {TextWidgetCmd procedure, "bbox" option} { list [catch {.t bbox} msg] $msg *************** *** 218,224 **** } {1 {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}} test text-6.14 {TextWidgetCmd procedure, "compare" option} { list [catch {.t co 1.0 z 1.2} msg] $msg ! } {1 {bad option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} # "configure" option is already covered above --- 220,228 ---- } {1 {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}} test text-6.14 {TextWidgetCmd procedure, "compare" option} { list [catch {.t co 1.0 z 1.2} msg] $msg ! } [ jp&orig \ ! {1 {bad option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, xypos, or yview}} \ ! {1 {bad option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} ] # "configure" option is already covered above *************** *** 227,233 **** } {1 {wrong # args: should be ".t debug boolean"}} test text-7.2 {TextWidgetCmd procedure, "debug" option} { list [catch {.t de 0 1} msg] $msg ! } {1 {bad option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} test text-7.3 {TextWidgetCmd procedure, "debug" option} { .t debug true .t deb --- 231,239 ---- } {1 {wrong # args: should be ".t debug boolean"}} test text-7.2 {TextWidgetCmd procedure, "debug" option} { list [catch {.t de 0 1} msg] $msg ! } [ jp&orig \ ! {1 {bad option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, xypos, or yview}} \ ! {1 {bad option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} ] test text-7.3 {TextWidgetCmd procedure, "debug" option} { .t debug true .t deb *************** *** 310,316 **** } {1 {wrong # args: should be ".t index index"}} test text-10.3 {TextWidgetCmd procedure, "index" option} { list [catch {.t in a b} msg] $msg ! } {1 {bad option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} test text-10.4 {TextWidgetCmd procedure, "index" option} { list [catch {.t index @xyz} msg] $msg } {1 {bad text index "@xyz"}} --- 316,324 ---- } {1 {wrong # args: should be ".t index index"}} test text-10.3 {TextWidgetCmd procedure, "index" option} { list [catch {.t in a b} msg] $msg ! } [ jp&orig \ ! {1 {bad option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, xypos, or yview}} \ ! {1 {bad option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}} ] test text-10.4 {TextWidgetCmd procedure, "index" option} { list [catch {.t index @xyz} msg] $msg } {1 {bad text index "@xyz"}} diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/textDisp.test ./tests/textDisp.test *** ../../tk8.0.5/tests/textDisp.test Tue Sep 15 03:23:50 1998 --- ./tests/textDisp.test Fri Mar 12 00:38:54 1999 *************** *** 14,19 **** --- 14,23 ---- if {$testConfig(fonts) == 0} { puts "skipping font-sensitive tests" } + } + + if {[string compare [info command kanji] "kanji"] == 0} { + font cache clear } # The procedure below is used as the scrolling command for the text; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/textImage.test ./tests/textImage.test *** ../../tk8.0.5/tests/textImage.test Tue Sep 15 03:23:51 1998 --- ./tests/textImage.test Fri Mar 12 00:38:55 1999 *************** *** 2,7 **** --- 2,11 ---- if {[string compare test [info procs test]] == 1} then \ {source ../tests/defs} + + if {[string compare kanji [info command kanji]] == 0} { + font cache clear + } # Test Arguments: # name - Name of test, in the form foo-1.2. diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/unixEmbed.test ./tests/unixEmbed.test *** ../../tk8.0.5/tests/unixEmbed.test Tue Dec 8 13:05:34 1998 --- ./tests/unixEmbed.test Fri Mar 12 00:38:57 1999 *************** *** 109,114 **** --- 109,115 ---- frame .f1 -container 1 -width 200 -height 50 frame .f2 -container 1 -width 200 -height 50 pack .f1 .f2 + update dobg "set w [winfo id .f1]" dobg { eval destroy [winfo child .] diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/unixFont.test ./tests/unixFont.test *** ../../tk8.0.5/tests/unixFont.test Tue Sep 15 03:23:52 1998 --- ./tests/unixFont.test Fri Mar 12 00:38:57 1999 *************** *** 22,28 **** if {[string compare test [info procs test]] != 0} { source defs } ! catch {destroy .b} toplevel .b wm geom .b +0+0 --- 22,30 ---- if {[string compare test [info procs test]] != 0} { source defs } ! if {[string compare kanji [info command kanji]] == 0} { ! font cache clear ! } catch {destroy .b} toplevel .b wm geom .b +0+0 *************** *** 62,101 **** } {} test unixfont-2.2 {TkpGetFontFromAttributes procedure: Times relatives} { set x {} ! lappend x [lindex [font actual {-family "Times New Roman"}] 1] ! lappend x [lindex [font actual {-family "New York"}] 1] ! lappend x [lindex [font actual {-family "Times"}] 1] } {times times times} test unixfont-2.3 {TkpGetFontFromAttributes procedure: Courier relatives} { set x {} ! lappend x [lindex [font actual {-family "Courier New"}] 1] ! lappend x [lindex [font actual {-family "Monaco"}] 1] ! lappend x [lindex [font actual {-family "Courier"}] 1] } {courier courier courier} test unixfont-2.4 {TkpGetFontFromAttributes procedure: Helvetica relatives} { set x {} ! lappend x [lindex [font actual {-family "Arial"}] 1] ! lappend x [lindex [font actual {-family "Geneva"}] 1] ! lappend x [lindex [font actual {-family "Helvetica"}] 1] } {helvetica helvetica helvetica} test unixfont-2.5 {TkpGetFontFromAttributes procedure: fallback} { font actual {-xyz-xyz-*-*-*-*-*-*-*-*-*-*-*-*} set x {} } {} test unixfont-2.6 {TkpGetFontFromAttributes: fallback to fixed family} { ! lindex [font actual {-family fixed -size 10}] 1 } {fixed} test unixfont-2.7 {TkpGetFontFromAttributes: fixed family not available!} { # no test available } {} test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} { ! lindex [font actual {-family fixed -size 31}] 1 } {fixed} test unixfont-2.9 {TkpGetFontFromAttributes: reject adobe courier if possible} { ! lindex [font actual {-family courier}] 1 } {courier} test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} { ! lindex [font actual {-family courier -size 37}] 3 } {37} test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} { # On Linux, XListFonts() was returning names for fonts that do not --- 64,103 ---- } {} test unixfont-2.2 {TkpGetFontFromAttributes procedure: Times relatives} { set x {} ! lappend x [lindex [font actual {-family "Times New Roman"}] [jp&orig 3 1]] ! lappend x [lindex [font actual {-family "New York"}] [jp&orig 3 1]] ! lappend x [lindex [font actual {-family "Times"}] [jp&orig 3 1]] } {times times times} test unixfont-2.3 {TkpGetFontFromAttributes procedure: Courier relatives} { set x {} ! lappend x [lindex [font actual {-family "Courier New"}] [jp&orig 3 1]] ! lappend x [lindex [font actual {-family "Monaco"}] [jp&orig 3 1]] ! lappend x [lindex [font actual {-family "Courier"}] [jp&orig 3 1]] } {courier courier courier} test unixfont-2.4 {TkpGetFontFromAttributes procedure: Helvetica relatives} { set x {} ! lappend x [lindex [font actual {-family "Arial"}] [jp&orig 3 1]] ! lappend x [lindex [font actual {-family "Geneva"}] [jp&orig 3 1]] ! lappend x [lindex [font actual {-family "Helvetica"}] [jp&orig 3 1]] } {helvetica helvetica helvetica} test unixfont-2.5 {TkpGetFontFromAttributes procedure: fallback} { font actual {-xyz-xyz-*-*-*-*-*-*-*-*-*-*-*-*} set x {} } {} test unixfont-2.6 {TkpGetFontFromAttributes: fallback to fixed family} { ! lindex [font actual {-family fixed -size 10}] [jp&orig 3 1] } {fixed} test unixfont-2.7 {TkpGetFontFromAttributes: fixed family not available!} { # no test available } {} test unixfont-2.8 {TkpGetFontFromAttributes: loop over returned font names} { ! lindex [font actual {-family fixed -size 31}] [jp&orig 3 1] } {fixed} test unixfont-2.9 {TkpGetFontFromAttributes: reject adobe courier if possible} { ! lindex [font actual {-family courier}] [jp&orig 3 1] } {courier} test unixfont-2.10 {TkpGetFontFromAttributes: scalable font found} { ! lindex [font actual {-family courier -size 37}] [jp&orig 5 3] } {37} test unixfont-2.11 {TkpGetFontFromAttributes: font cannot be loaded} { # On Linux, XListFonts() was returning names for fonts that do not *************** *** 222,228 **** font delete xyz } {} test unixfont-8.2 {AllocFont procedure: parse information from XLFD} { ! expr [lindex [font actual {-family times -size 0}] 3]==0 } {0} test unixfont-8.3 {AllocFont procedure: can't parse info from name} { if [catch {set a [font actual a12biluc]}]==0 { --- 224,230 ---- font delete xyz } {} test unixfont-8.2 {AllocFont procedure: parse information from XLFD} { ! expr [lindex [font actual {-family times -size 0}] [jp&orig 5 3]]==0 } {0} test unixfont-8.3 {AllocFont procedure: can't parse info from name} { if [catch {set a [font actual a12biluc]}]==0 { *************** *** 291,293 **** --- 293,298 ---- lappend x [.b.c index $t @[expr $ax*5],0] } {0 1 1 1 1 2} + if {[string compare kanji [info command kanji]] == 0} { + font cache clear + } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/unixWm.test ./tests/unixWm.test *** ../../tk8.0.5/tests/unixWm.test Fri Feb 5 06:03:28 1999 --- ./tests/unixWm.test Fri Mar 12 00:38:58 1999 *************** *** 1503,1514 **** --- 1503,1516 ---- } {180 20 180 20} test unixWm-44.10 {UpdateGeometryInfo procedure, menubar changing} { catch {destroy .t} + update toplevel .t -width 80 -height 60 wm resizable .t 0 0 wm geometry .t +0+0 tkwait visibility .t .t configure -width 180 -height 50 frame .t.m -bd 2 -relief raised -width 100 -height 50 + update testmenubar window .t .t.m update .t configure -height 70 *************** *** 2356,2359 **** --- 2358,2363 ---- catch {destroy .t} catch {removeFile script} + + file delete -force script concat {} diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/tests/winFont.test ./tests/winFont.test *** ../../tk8.0.5/tests/winFont.test Tue Sep 15 03:23:53 1998 --- ./tests/winFont.test Fri Mar 12 00:39:00 1999 *************** *** 174,180 **** } {} test winfont-7.2 {AllocFont procedure: extract info from logfont} { font actual {arial 10 bold italic underline overstrike} ! } {-family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1} test winfont-7.3 {AllocFont procedure: extract info from textmetric} { font metric {arial 10 bold italic underline overstrike} -fixed } {0} --- 174,182 ---- } {} test winfont-7.2 {AllocFont procedure: extract info from logfont} { font actual {arial 10 bold italic underline overstrike} ! } [jp&orig \ ! {-foundry {} -family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1 -charset default -pointadjust 0 -compound {}} \ ! {-family Arial -size 10 -weight bold -slant italic -underline 1 -overstrike 1} ] test winfont-7.3 {AllocFont procedure: extract info from textmetric} { font metric {arial 10 bold italic underline overstrike} -fixed } {0} diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/Font.c ./unix/CacheLib/Font.c *** ../../tk8.0.5/unix/CacheLib/Font.c Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/Font.c Sat Dec 5 05:01:39 1998 *************** *** 0 **** --- 1,248 ---- + /* $XConsortium: Font.c /main/29 1996/10/22 14:18:35 kaleb $ */ + /* + + Copyright (c) 1986 X Consortium + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the X Consortium shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the X Consortium. + + */ + + #ifdef USE_OWN_XLQFONT + static int Tk_Use_Own_XLoadQueryFont = 1; + #define NEED_REPLIES + #include "Xlibint.h" + #include "tkPort.h" + #include "tkInt.h" + #include "tkUnixInt.h" + + static XFontStruct * _TkUnix__XQueryFont _ANSI_ARGS_((Display *dpy, Font fid, unsigned long seq)); + + XFontStruct * + TkUnixXLoadQueryFont(dpy, name) + register Display *dpy; + char *name; + { + XFontStruct *font_result; + register unsigned long nbytes; + Font fid; + xOpenFontReq *req; + unsigned long seq; + + LockDisplay(dpy); + GetReq(OpenFont, req); + seq = dpy->request; + nbytes = req->nbytes = name ? strlen(name) : 0; + req->fid = fid = XAllocID(dpy); + req->length += (nbytes+3)>>2; + Data (dpy, name, nbytes); + font_result = _TkUnix__XQueryFont(dpy, fid, seq); + UnlockDisplay(dpy); + SyncHandle(); + + return font_result; + } + + + int + TkUnixXFreeFont(dpy, fs) + register Display *dpy; + XFontStruct *fs; + { + register xResourceReq *req; + register _XExtension *ext; + + LockDisplay(dpy); + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->free_Font) (*ext->free_Font)(dpy, fs, &ext->codes); + GetResReq (CloseFont, fs->fid, req); + UnlockDisplay(dpy); + SyncHandle(); + _XFreeExtData(fs->ext_data); + if (fs->per_char) + Xfree ((char *) fs->per_char); + if (fs->properties) + Xfree ((char *) fs->properties); + Xfree ((char *) fs); + + return 1; + } + + + static XFontStruct * + _TkUnix__XQueryFont (dpy, fid, seq) + register Display *dpy; + Font fid; + unsigned long seq; + { + register XFontStruct *fs; + register long nbytes; + xQueryFontReply reply; + register xResourceReq *req; + register _XExtension *ext; + _XAsyncHandler async; + _XAsyncErrorState async_state; + + if (seq) { + async_state.min_sequence_number = seq; + async_state.max_sequence_number = seq; + async_state.error_code = BadName; + async_state.major_opcode = X_OpenFont; + async_state.minor_opcode = 0; + async_state.error_count = 0; + async.next = dpy->async_handlers; + async.handler = _XAsyncErrorHandler; + async.data = (XPointer)&async_state; + dpy->async_handlers = &async; + } + GetResReq(QueryFont, fid, req); + if (!_XReply (dpy, (xReply *) &reply, + ((SIZEOF(xQueryFontReply) - SIZEOF(xReply)) >> 2), xFalse)) { + if (seq) + DeqAsyncHandler(dpy, &async); + return (XFontStruct *)NULL; + } + if (seq) + DeqAsyncHandler(dpy, &async); + if (! (fs = (XFontStruct *) Xmalloc (sizeof (XFontStruct)))) { + _XEatData(dpy, (unsigned long)(reply.nFontProps * SIZEOF(xFontProp) + + reply.nCharInfos * SIZEOF(xCharInfo))); + return (XFontStruct *)NULL; + } + fs->ext_data = NULL; + fs->fid = fid; + fs->direction = reply.drawDirection; + fs->min_char_or_byte2 = reply.minCharOrByte2; + fs->max_char_or_byte2 = reply.maxCharOrByte2; + fs->min_byte1 = reply.minByte1; + fs->max_byte1 = reply.maxByte1; + fs->default_char = reply.defaultChar; + fs->all_chars_exist = reply.allCharsExist; + fs->ascent = cvtINT16toInt (reply.fontAscent); + fs->descent = cvtINT16toInt (reply.fontDescent); + + #ifdef MUSTCOPY + { + xCharInfo *xcip; + + xcip = (xCharInfo *) &reply.minBounds; + fs->min_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing); + fs->min_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing); + fs->min_bounds.width = cvtINT16toShort(xcip->characterWidth); + fs->min_bounds.ascent = cvtINT16toShort(xcip->ascent); + fs->min_bounds.descent = cvtINT16toShort(xcip->descent); + fs->min_bounds.attributes = xcip->attributes; + + xcip = (xCharInfo *) &reply.maxBounds; + fs->max_bounds.lbearing = cvtINT16toShort(xcip->leftSideBearing); + fs->max_bounds.rbearing = cvtINT16toShort(xcip->rightSideBearing); + fs->max_bounds.width = cvtINT16toShort(xcip->characterWidth); + fs->max_bounds.ascent = cvtINT16toShort(xcip->ascent); + fs->max_bounds.descent = cvtINT16toShort(xcip->descent); + fs->max_bounds.attributes = xcip->attributes; + } + #else + /* XXX the next two statements won't work if short isn't 16 bits */ + fs->min_bounds = * (XCharStruct *) &reply.minBounds; + fs->max_bounds = * (XCharStruct *) &reply.maxBounds; + #endif /* MUSTCOPY */ + + fs->n_properties = reply.nFontProps; + /* + * if no properties defined for the font, then it is bad + * font, but shouldn't try to read nothing. + */ + fs->properties = NULL; + if (fs->n_properties > 0) { + nbytes = reply.nFontProps * sizeof(XFontProp); + fs->properties = (XFontProp *) Xmalloc ((unsigned) nbytes); + nbytes = reply.nFontProps * SIZEOF(xFontProp); + if (! fs->properties) { + Xfree((char *) fs); + _XEatData(dpy, (unsigned long) + (nbytes + reply.nCharInfos * SIZEOF(xCharInfo))); + return (XFontStruct *)NULL; + } + _XRead32 (dpy, (char *)fs->properties, nbytes); + } + /* + * If no characters in font, then it is a bad font, but + * shouldn't try to read nothing. + */ + /* have to unpack charinfos on some machines (CRAY) */ + fs->per_char = NULL; + if (reply.nCharInfos > 0){ + nbytes = reply.nCharInfos * sizeof(XCharStruct); + if (! (fs->per_char = (XCharStruct *) Xmalloc ((unsigned) nbytes))) { + if (fs->properties) Xfree((char *) fs->properties); + Xfree((char *) fs); + _XEatData(dpy, (unsigned long) + (reply.nCharInfos * SIZEOF(xCharInfo))); + return (XFontStruct *)NULL; + } + + #ifdef MUSTCOPY + { + register XCharStruct *cs = fs->per_char; + register int i; + + for (i = 0; i < reply.nCharInfos; i++, cs++) { + xCharInfo xcip; + + _XRead(dpy, (char *)&xcip, SIZEOF(xCharInfo)); + cs->lbearing = cvtINT16toShort(xcip.leftSideBearing); + cs->rbearing = cvtINT16toShort(xcip.rightSideBearing); + cs->width = cvtINT16toShort(xcip.characterWidth); + cs->ascent = cvtINT16toShort(xcip.ascent); + cs->descent = cvtINT16toShort(xcip.descent); + cs->attributes = xcip.attributes; + } + } + #else + nbytes = reply.nCharInfos * SIZEOF(xCharInfo); + _XRead16 (dpy, (char *)fs->per_char, nbytes); + #endif + } + + /* call out to any extensions interested */ + for (ext = dpy->ext_procs; ext; ext = ext->next) + if (ext->create_Font) (*ext->create_Font)(dpy, fs, &ext->codes); + return fs; + } + + + XFontStruct * + TkUnixXQueryFont (dpy, fid) + register Display *dpy; + Font fid; + { + XFontStruct *font_result; + + LockDisplay(dpy); + font_result = _TkUnix__XQueryFont(dpy, fid, 0L); + UnlockDisplay(dpy); + SyncHandle(); + return font_result; + } + #else + static int Tk_Use_Own_XLoadQueryFont = 0; + #endif /* USE_OWN_XLQFONT */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/FontNames.c ./unix/CacheLib/FontNames.c *** ../../tk8.0.5/unix/CacheLib/FontNames.c Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/FontNames.c Thu Aug 6 16:48:06 1998 *************** *** 0 **** --- 1,114 ---- + /* $XConsortium: FontNames.c /main/12 1996/10/22 14:18:43 kaleb $ */ + /* + + Copyright (c) 1986 X Consortium + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the X Consortium shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the X Consortium. + + */ + + #ifdef USE_OWN_XLSFONT + static int Tk_Use_Own_XListFonts = 1; + #define NEED_REPLIES + #include "Xlibint.h" + + #include "tk.h" + + char ** + TkUnixXListFonts(dpy, pattern, maxNames, actualCount) + register Display *dpy; + char *pattern; /* null-terminated */ + int maxNames; + int *actualCount; /* RETURN */ + { + register long nbytes; + register unsigned i; + register int length; + char **flist; + char *ch; + xListFontsReply rep; + register xListFontsReq *req; + register long rlen; + + LockDisplay(dpy); + GetReq(ListFonts, req); + req->maxNames = maxNames; + nbytes = req->nbytes = pattern ? strlen (pattern) : 0; + req->length += (nbytes + 3) >> 2; + _XSend (dpy, pattern, nbytes); + /* use _XSend instead of Data, since following _XReply will flush buffer */ + + (void) _XReply (dpy, (xReply *)&rep, 0, xFalse); + + if (rep.nFonts) { + flist = (char **)Xmalloc ((unsigned)rep.nFonts * sizeof(char *)); + rlen = rep.length << 2; + ch = (char *) Xmalloc((unsigned) (rlen + 1)); + /* +1 to leave room for last null-terminator */ + + if ((! flist) || (! ch)) { + if (flist) Xfree((char *) flist); + if (ch) Xfree(ch); + _XEatData(dpy, (unsigned long) rlen); + UnlockDisplay(dpy); + SyncHandle(); + return (char **) NULL; + } + + _XReadPad (dpy, ch, rlen); + /* + * unpack into null terminated strings. + */ + length = *(unsigned char *)ch; + *ch = 1; /* make sure it is non-zero for XFreeFontNames */ + for (i = 0; i < rep.nFonts; i++) { + flist[i] = ch + 1; /* skip over length */ + ch += length + 1; /* find next length ... */ + length = *(unsigned char *)ch; + *ch = '\0'; /* and replace with null-termination */ + } + } + else flist = (char **) NULL; + *actualCount = rep.nFonts; + UnlockDisplay(dpy); + SyncHandle(); + return (flist); + } + + int + TkUnixXFreeFontNames(list) + char **list; + { + if (list) { + if (!*(list[0]-1)) { /* from ListFontsWithInfo */ + register char **names; + for (names = list+1; *names; names++) + Xfree (*names); + } + Xfree (list[0]-1); + Xfree ((char *)list); + } + return 1; + } + #else + static int Tk_Use_Own_XListFonts = 0; + #endif /* USE_OWN_XLSFONT */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/XlcPublic.h ./unix/CacheLib/XlcPublic.h *** ../../tk8.0.5/unix/CacheLib/XlcPublic.h Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/XlcPublic.h Thu Aug 6 16:48:06 1998 *************** *** 0 **** --- 1,287 ---- + /* $TOG: XlcPublic.h /main/6 1997/06/22 07:38:55 kaleb $ */ + /* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + /* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + + #ifndef _XLCPUBLIC_H_ + #define _XLCPUBLIC_H_ + + #include "Xlcint.h" + + #define XlcNCharSize "charSize" + #define XlcNCodeset "codeset" + #define XlcNControlSequence "controlSequence" + #define XlcNDefaultString "defaultString" + #define XlcNEncodingName "encodingName" + #define XlcNLanguage "language" + #define XlcNMbCurMax "mbCurMax" + #define XlcNName "name" + #define XlcNSetSize "setSize" + #define XlcNSide "side" + #define XlcNStateDependentEncoding "stateDependentEncoding" + #define XlcNTerritory "territory" + + typedef enum { + XlcUnknown, XlcC0, XlcGL, XlcC1, XlcGR, XlcGLGR, XlcOther, XlcNONE + } XlcSide; + + typedef struct _FontScope { + unsigned long start; + unsigned long end; + unsigned long shift; + unsigned long shift_direction; + } FontScopeRec, *FontScope; + + typedef struct _UDCArea { + unsigned long start,end; + } UDCAreaRec, *UDCArea; + + typedef struct _XlcCharSetRec *XlcCharSet; + + typedef char* (*XlcGetCSValuesProc)( + #if NeedFunctionPrototypes + XlcCharSet /* charset */, + XlcArgList /* args */, + int /* num_args */ + #endif + ); + + typedef struct _XlcCharSetRec { + char *name; /* character set name */ + XrmQuark xrm_name; + char *encoding_name; /* XLFD encoding name */ + XrmQuark xrm_encoding_name; + XlcSide side; /* GL, GR or others */ + int char_size; /* number of bytes per character */ + int set_size; /* graphic character sets */ + char *ct_sequence; /* control sequence of CT */ + XlcGetCSValuesProc get_values; + /* UDC */ + Bool string_encoding; + UDCArea udc_area; + int udc_area_num; + } XlcCharSetRec; + + /* + * conversion methods + */ + + typedef struct _XlcConvRec *XlcConv; + + typedef XlcConv (*XlcOpenConverterProc)( + #if NeedFunctionPrototypes + XLCd /* from_lcd */, + char* /* from_type */, + XLCd /* to_lcd */, + char* /* to_type */ + #endif + ); + + typedef void (*XlcCloseConverterProc)( + #if NeedFunctionPrototypes + XlcConv /* conv */ + #endif + ); + + typedef int (*XlcConvertProc)( + #if NeedFunctionPrototypes + XlcConv /* conv */, + XPointer* /* from */, + int* /* from_left */, + XPointer* /* to */, + int* /* to_left */, + XPointer* /* args */, + int /* num_args */ + #endif + ); + + typedef void (*XlcResetConverterProc)( + #if NeedFunctionPrototypes + XlcConv /* conv */ + #endif + ); + + typedef struct _XlcConvMethodsRec{ + XlcCloseConverterProc close; + XlcConvertProc convert; + XlcResetConverterProc reset; + } XlcConvMethodsRec, *XlcConvMethods; + + /* + * conversion data + */ + + #define XlcNMultiByte "multiByte" + #define XlcNWideChar "wideChar" + #define XlcNCompoundText "compoundText" + #define XlcNString "string" + #define XlcNCharSet "charSet" + #define XlcNCTCharSet "CTcharSet" + #define XlcNChar "char" + + typedef struct _XlcConvRec { + XlcConvMethods methods; + XPointer state; + } XlcConvRec; + + + _XFUNCPROTOBEGIN + + extern Bool _XInitOM( + #if NeedFunctionPrototypes + XLCd /* lcd */ + #endif + ); + + extern Bool _XInitIM( + #if NeedFunctionPrototypes + XLCd /* lcd */ + #endif + ); + + extern char *_XGetLCValues( + #if NeedVarargsPrototypes + XLCd /* lcd */, + ... + #endif + ); + + extern XlcCharSet _XlcGetCharSet( + #if NeedFunctionPrototypes + char* /* name */ + #endif + ); + + extern Bool _XlcAddCharSet( + #if NeedFunctionPrototypes + XlcCharSet /* charset */ + #endif + ); + + extern char *_XlcGetCSValues( + #if NeedVarargsPrototypes + XlcCharSet /* charset */, + ... + #endif + ); + + extern XlcConv _XlcOpenConverter( + #if NeedFunctionPrototypes + XLCd /* from_lcd */, + char* /* from_type */, + XLCd /* to_lcd */, + char* /* to_type */ + #endif + ); + + extern void _XlcCloseConverter( + #if NeedFunctionPrototypes + XlcConv /* conv */ + #endif + ); + + extern int _XlcConvert( + #if NeedFunctionPrototypes + XlcConv /* conv */, + XPointer* /* from */, + int* /* from_left */, + XPointer* /* to */, + int* /* to_left */, + XPointer* /* args */, + int /* num_args */ + #endif + ); + + extern void _XlcResetConverter( + #if NeedFunctionPrototypes + XlcConv /* conv */ + #endif + ); + + extern Bool _XlcSetConverter( + #if NeedFunctionPrototypes + XLCd /* from_lcd */, + char* /* from_type */, + XLCd /* to_lcd */, + char* /* to_type */, + XlcOpenConverterProc /* open_converter */ + #endif + ); + + extern void _XlcGetResource( + #if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* category */, + char* /* class */, + char*** /* value */, + int* /* count */ + #endif + ); + + extern char *_XlcFileName( + #if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* category */ + #endif + ); + + extern int _Xwcslen( + #if NeedFunctionPrototypes + wchar_t* /* wstr */ + #endif + ); + + extern wchar_t *_Xwcscpy( + #if NeedFunctionPrototypes + wchar_t* /* wstr1 */, + wchar_t* /* wstr2 */ + #endif + ); + + extern int _XlcCompareISOLatin1( + #if NeedFunctionPrototypes + char* /* str1 */, + char* /* str2 */ + #endif + ); + + extern int _XlcNCompareISOLatin1( + #if NeedFunctionPrototypes + char* /* str1 */, + char* /* str2 */, + int /* len */ + #endif + ); + + _XFUNCPROTOEND + + #endif /* _XLCPUBLIC_H_ */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/Xlcint.h ./unix/CacheLib/Xlcint.h *** ../../tk8.0.5/unix/CacheLib/Xlcint.h Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/Xlcint.h Thu Aug 6 16:48:07 1998 *************** *** 0 **** --- 1,1006 ---- + /* $XConsortium: Xlcint.h /main/25 1996/09/28 16:35:19 rws $ */ + /* + + Copyright (c) 1991 X Consortium + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the X Consortium shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the X Consortium. + + */ + + /* + * Copyright 1990, 1991 by OMRON Corporation, NTT Software Corporation, + * and Nippon Telegraph and Telephone Corporation + * Copyright 1991 by the Open Software Foundation + * Copyright 1993 by the TOSHIBA Corp. + * Copyright 1993, 1994 by Sony Corporation + * Copyright 1993, 1994 by the FUJITSU LIMITED + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the names of OMRON, NTT Software, NTT, Open + * Software Foundation, and Sony Corporation not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. OMRON, NTT Software, NTT, Open Software + * Foundation, and Sony Corporation make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, AND SONY + * CORPORATION DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT + * SHALL OMRON, NTT SOFTWARE, NTT, OPEN SOFTWARE FOUNDATION, OR SONY + * CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Authors: Li Yuhong OMRON Corporation + * Tatsuya Kato NTT Software Corporation + * Hiroshi Kuribayashi OMRON Coproration + * Muneiyoshi Suzuki Nippon Telegraph and Telephone Co. + * + * M. Collins OSF + * Katsuhisa Yano TOSHIBA Corp. + * Makoto Wakamatsu Sony Corporation + * Takashi Fujiwara FUJITSU LIMITED + */ + /* $XFree86: xc/lib/X11/Xlcint.h,v 3.1.2.3 1998/01/25 06:11:04 dawes Exp $ */ + + + #ifndef _XLCINT_H_ + #define _XLCINT_H_ + + #include + #include + #include "Xvarargs.h" + + typedef Bool (*XFilterEventProc)( + #if NeedFunctionPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ + #endif + ); + + typedef struct _XIMFilter { + struct _XIMFilter *next; + Window window; + unsigned long event_mask; + int start_type, end_type; + XFilterEventProc filter; + XPointer client_data; + } XFilterEventRec, *XFilterEventList; + + typedef struct { + char *name; + XPointer value; + } XIMArg; + + #ifdef offsetof + #define XOffsetOf(s_type,field) offsetof(s_type,field) + #else + #define XOffsetOf(s_type,field) ((unsigned int)&(((s_type*)NULL)->field)) + #endif + + #define XIMNumber(arr) ((unsigned int) (sizeof(arr) / sizeof(arr[0]))) + + /* + * define secondary data structs which are part of Input Methods + * and Input Context + */ + typedef struct { + char *resource_name; /* Resource string */ + XrmQuark xrm_name; /* Resource name quark */ + int resource_size; /* Size in bytes of data */ + long resource_offset; /* Offset from base */ + unsigned short mode; /* Read Write Permission */ + unsigned short id; /* Input Method Protocol */ + } XIMResource, *XIMResourceList; + + /* + * data block describing the visual attributes associated with + * an input context + */ + typedef struct { + XRectangle area; + XRectangle area_needed; + XPoint spot_location; + Colormap colormap; + Atom std_colormap; + unsigned long foreground; + unsigned long background; + Pixmap background_pixmap; + XFontSet fontset; + int line_spacing; + Cursor cursor; + XICCallback start_callback; + XICCallback done_callback; + XICCallback draw_callback; + XICCallback caret_callback; + XIMPreeditState preedit_state; + XICCallback state_notify_callback; + } ICPreeditAttributes, *ICPreeditAttributesPtr; + + typedef struct { + XRectangle area; + XRectangle area_needed; + Colormap colormap; + Atom std_colormap; + unsigned long foreground; + unsigned long background; + Pixmap background_pixmap; + XFontSet fontset; + int line_spacing; + Cursor cursor; + XICCallback start_callback; + XICCallback done_callback; + XICCallback draw_callback; + } ICStatusAttributes, *ICStatusAttributesPtr; + + /* + * Methods for Xrm parsing + */ + + typedef void (*XmbInitProc)( + #if NeedFunctionPrototypes + XPointer /* state */ + #endif + ); + + typedef char (*XmbCharProc)( + #if NeedFunctionPrototypes + XPointer /* state */, + char* /* str */, + int* /* lenp */ + #endif + ); + + typedef void (*XmbFinishProc)( + #if NeedFunctionPrototypes + XPointer /* state */ + #endif + ); + + typedef char* (*XlcNameProc)( + #if NeedFunctionPrototypes + XPointer /* state */ + #endif + ); + + typedef void (*XrmDestroyProc)( + #if NeedFunctionPrototypes + XPointer /* state */ + #endif + ); + + typedef struct { + XmbInitProc mbinit; + XmbCharProc mbchar; + XmbFinishProc mbfinish; + XlcNameProc lcname; + XrmDestroyProc destroy; + } XrmMethodsRec, *XrmMethods; + + typedef struct _XLCd *XLCd; /* need forward reference */ + + /* + * define an LC, it's methods, and data. + */ + + typedef void (*XCloseLCProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */ + #endif + ); + + typedef char* (*XlcMapModifiersProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* user_mods */, + char* /* prog_mods */ + #endif + ); + + typedef XOM (*XOpenOMProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + _Xconst char* /* res_name */, + _Xconst char* /* res_class */ + #endif + ); + + typedef XIM (*XOpenIMProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + char* /* res_name */, + char* /* res_class */ + #endif + ); + + typedef Bool (*XRegisterIMInstantiateCBProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIDProc /* callback */, + XPointer /* client_data */ + #endif + ); + + typedef Bool (*XUnregisterIMInstantiateCBProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XrmDatabase /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIDProc /* callback */, + XPointer /* client_data */ + #endif + ); + + typedef XrmMethods (*XrmInitParseInfoProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + XPointer* /* state */ + #endif + ); + + typedef int (*XmbTextPropertyToTextListProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XTextProperty* /* text_prop */, + char*** /* list_return */, + int* /* count_return */ + #endif + ); + + typedef int (*XwcTextPropertyToTextListProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + XTextProperty* /* text_prop */, + wchar_t*** /* list_return */, + int* /* count_return */ + #endif + ); + + typedef int (*XmbTextListToTextPropertyProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + char** /* list */, + int /* count */, + XICCEncodingStyle /* style */, + XTextProperty* /* text_prop_return */ + #endif + ); + + typedef int (*XwcTextListToTextPropertyProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* display */, + wchar_t** /* list */, + int /* count */, + XICCEncodingStyle /* style */, + XTextProperty* /* text_prop_return */ + #endif + ); + + typedef void (*XwcFreeStringListProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */, + wchar_t** /* list */ + #endif + ); + + typedef char* (*XDefaultStringProc)( + #if NeedFunctionPrototypes + XLCd /* lcd */ + #endif + ); + + typedef struct { + XCloseLCProc close; + XlcMapModifiersProc map_modifiers; + XOpenOMProc open_om; + XOpenIMProc open_im; + XrmInitParseInfoProc init_parse_info; + XmbTextPropertyToTextListProc mb_text_prop_to_list; + XwcTextPropertyToTextListProc wc_text_prop_to_list; + XmbTextListToTextPropertyProc mb_text_list_to_prop; + XwcTextListToTextPropertyProc wc_text_list_to_prop; + XwcFreeStringListProc wc_free_string_list; + XDefaultStringProc default_string; + XRegisterIMInstantiateCBProc register_callback; + XUnregisterIMInstantiateCBProc unregister_callback; + } XLCdMethodsRec, *XLCdMethods; + + + typedef struct { + char* name; /* name of this LC */ + char* modifiers; /* modifiers of locale */ + } XLCdCoreRec, *XLCdCore; + + + typedef struct _XLCd { + XLCdMethods methods; /* methods of this LC */ + XLCdCore core; /* data of this LC */ + XPointer opaque; /* LDX specific data */ + } XLCdRec; + + typedef int XlcPosition; + + #define XlcHead 0 + #define XlcTail -1 + + typedef struct { + char *name; + XPointer value; + } XlcArg, *XlcArgList; + + typedef struct _XlcResource { + char *name; + XrmQuark xrm_name; + int size; + int offset; + unsigned long mask; + } XlcResource, *XlcResourceList; + + #define XlcCreateMask (1L<<0) + #define XlcDefaultMask (1L<<1) + #define XlcGetMask (1L<<2) + #define XlcSetMask (1L<<3) + #define XlcIgnoreMask (1L<<4) + + #define XlcNumber(arr) (sizeof(arr) / sizeof(arr[0])) + + typedef Status (*XCloseOMProc)( + #if NeedFunctionPrototypes + XOM /* om */ + #endif + ); + + typedef char* (*XSetOMValuesProc)( + #if NeedFunctionPrototypes + XOM /* om */, + XlcArgList /* args */, + int /* num_args */ + #endif + ); + + typedef char* (*XGetOMValuesProc)( + #if NeedFunctionPrototypes + XOM /* om */, + XlcArgList /* args */, + int /* num_args */ + #endif + ); + + typedef XOC (*XCreateOCProc)( + #if NeedFunctionPrototypes + XOM /* om */, + XlcArgList /* args */, + int /* num_args */ + #endif + ); + + typedef struct _XOMMethodsRec { + XCloseOMProc close; + XSetOMValuesProc set_values; + XGetOMValuesProc get_values; + XCreateOCProc create_oc; + } XOMMethodsRec, *XOMMethods; + + typedef struct _XOMCoreRec { + XLCd lcd; /* lcd */ + Display *display; /* display */ + XrmDatabase rdb; /* database */ + char *res_name; /* resource name */ + char *res_class; /* resource class */ + XOC oc_list; /* xoc list */ + XlcResourceList resources; /* xom resources */ + int num_resources; /* number of xom resources */ + XOMCharSetList required_charset; /* required charset list */ + XOMOrientation orientation_list; /* orientation list */ + Bool directional_dependent; /* directional-dependent */ + Bool contextual_drawing; /* contextual drawing */ + Bool context_dependent; /* context-dependent drawing */ + } XOMCoreRec, *XOMCore; + + typedef struct _XOM { + XOMMethods methods; + XOMCoreRec core; + } XOMRec; + + typedef void (*XDestroyOCProc)( + #if NeedFunctionPrototypes + XOC /* oc */ + #endif + ); + + typedef char* (*XSetOCValuesProc)( + #if NeedFunctionPrototypes + XOC /* oc */, + XlcArgList /* args */, + int /* num_args */ + #endif + ); + + typedef char* (*XGetOCValuesProc)( + #if NeedFunctionPrototypes + XOC /* oc */, + XlcArgList /* args */, + int /* num_args */ + #endif + ); + + /* + * X Font Sets are an instantiable object, so we define it, the + * object itself, a method list and data + */ + + /* + * XFontSet object method list + */ + + typedef int (*XmbTextEscapementProc)( + #if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* text_len */ + #endif + ); + + typedef int (*XmbTextExtentsProc)( + #if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* text_len */, + XRectangle* /* overall_ink_extents */, + XRectangle* /* overall_logical_extents */ + #endif + ); + + typedef Status (*XmbTextPerCharExtentsProc)( + #if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* text_len */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* max_ink_extents */, + XRectangle* /* max_logical_extents */ + #endif + ); + + typedef int (*XmbDrawStringProc)( + #if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* text_len */ + #endif + ); + + typedef void (*XmbDrawImageStringProc)( + #if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* text_len */ + #endif + ); + + typedef int (*XwcTextEscapementProc)( + #if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* text_len */ + #endif + ); + + typedef int (*XwcTextExtentsProc)( + #if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* text_len */, + XRectangle* /* overall_ink_extents */, + XRectangle* /* overall_logical_extents */ + #endif + ); + + typedef Status (*XwcTextPerCharExtentsProc)( + #if NeedFunctionPrototypes + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* text_len */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* max_ink_extents */, + XRectangle* /* max_logical_extents */ + #endif + ); + + typedef int (*XwcDrawStringProc)( + #if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* text_len */ + #endif + ); + + typedef void (*XwcDrawImageStringProc)( + #if NeedFunctionPrototypes + Display* /* display */, + Drawable /* drawable */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* text_len */ + #endif + ); + + typedef struct { + XDestroyOCProc destroy; + XSetOCValuesProc set_values; + XGetOCValuesProc get_values; + + /* multi-byte text drawing methods */ + + XmbTextEscapementProc mb_escapement; + XmbTextExtentsProc mb_extents; + XmbTextPerCharExtentsProc mb_extents_per_char; + XmbDrawStringProc mb_draw_string; + XmbDrawImageStringProc mb_draw_image_string; + + /* wide character text drawing methods */ + + XwcTextEscapementProc wc_escapement; + XwcTextExtentsProc wc_extents; + XwcTextPerCharExtentsProc wc_extents_per_char; + XwcDrawStringProc wc_draw_string; + XwcDrawImageStringProc wc_draw_image_string; + } XOCMethodsRec, *XOCMethods; + + + /* + * XOC independent data + */ + + typedef struct { + XOM om; /* XOM */ + XOC next; /* next XOC */ + XlcResourceList resources; /* xoc resources */ + int num_resources; /* number of xoc resources */ + char *base_name_list; /* base font name list */ + Bool om_automatic; /* OM Automatic */ + XOMFontInfo font_info; /* font info */ + XFontSetExtents font_set_extents; /* font set extents */ + char *default_string; /* default string */ + XOMCharSetList missing_list; /* missing charset list */ + XOrientation orientation; /* orientation */ + char *res_name; /* resource name */ + char *res_class; /* resource class */ + } XOCCoreRec, *XOCCore; + + typedef struct _XOC { + XOCMethods methods; + XOCCoreRec core; + } XOCRec; + + + /* current Ultrix compiler gets horribly confused */ + #if defined(FUNCPROTO) && defined(ultrix) + #undef NeedFunctionPrototypes + #endif + + + /* + * X Input Managers are an instantiable object, so we define it, the + * object itself, a method list and data. + */ + + /* + * an Input Manager object method list + */ + typedef struct { + Status (*close)( + #if NeedFunctionPrototypes + XIM + #endif + ); + char* (*set_values)( + #if NeedFunctionPrototypes + XIM, XIMArg* + #endif + ); + char* (*get_values)( + #if NeedFunctionPrototypes + XIM, XIMArg* + #endif + ); + XIC (*create_ic)( + #if NeedFunctionPrototypes + XIM, XIMArg* + #endif + ); + int (*ctstombs)( + #if NeedFunctionPrototypes + XIM, char*, int, char*, int, Status * + #endif + ); + int (*ctstowcs)( + #if NeedFunctionPrototypes + XIM, char*, int, wchar_t*, int, Status * + #endif + ); + } XIMMethodsRec, *XIMMethods; + + /* + * Input Manager LC independent data + */ + typedef struct { + XLCd lcd; /* LC of this input method */ + XIC ic_chain; /* list of ICs for this IM */ + + Display * display; /* display */ + XrmDatabase rdb; + char * res_name; + char * res_class; + + XIMValuesList *im_values_list; + XIMValuesList *ic_values_list; + XIMStyles *styles; + XIMCallback destroy_callback; + char * im_name; /* XIMMODIFIER name */ + XIMResourceList im_resources; /* compiled IM resource list */ + unsigned int im_num_resources; + XIMResourceList ic_resources; /* compiled IC resource list */ + unsigned int ic_num_resources; + Bool visible_position; + } XIMCoreRec, *XIMCore; + + + + /* + * An X Input Manager (IM). Implementations may need to extend this data + * structure to accomodate additional data, state information etc. + */ + typedef struct _XIM { + XIMMethods methods; /* method list of this IM */ + XIMCoreRec core; /* data of this IM */ + } XIMRec; + + + + /* + * X Input Contexts (IC) are an instantiable object, so we define it, the + * object itself, a method list and data for this object + */ + + /* + * Input Context method list + */ + typedef struct { + void (*destroy)( + #if NeedFunctionPrototypes + XIC + #endif + ); + void (*set_focus)( + #if NeedFunctionPrototypes + XIC + #endif + ); + void (*unset_focus)( + #if NeedFunctionPrototypes + XIC + #endif + ); + char* (*set_values)( + #if NeedFunctionPrototypes + XIC, XIMArg* + #endif + ); + char* (*get_values)( + #if NeedFunctionPrototypes + XIC, XIMArg* + #endif + ); + char* (*mb_reset)( + #if NeedFunctionPrototypes + XIC + #endif + ); + wchar_t* (*wc_reset)( + #if NeedFunctionPrototypes + XIC + #endif + ); + int (*mb_lookup_string)( + #if NeedFunctionPrototypes + XIC, XKeyEvent*, char*, int, KeySym*, Status* + #endif + ); + int (*wc_lookup_string)( + #if NeedFunctionPrototypes + XIC, XKeyEvent*, wchar_t*, int, KeySym*, Status* + #endif + ); + } XICMethodsRec, *XICMethods; + + + /* + * Input Context LC independent data + */ + typedef struct { + XIM im; /* XIM this IC belongs too */ + XIC next; /* linked list of ICs for IM */ + + Window client_window; /* window IM can use for */ + /* display or subwindows */ + XIMStyle input_style; /* IM's input style */ + Window focus_window; /* where key events go */ + unsigned long filter_events; /* event mask from IM */ + XICCallback geometry_callback; /* client callback */ + char * res_name; + char * res_class; + + XICCallback destroy_callback; + XICCallback string_conversion_callback; + XIMStringConversionText string_conversion; + XIMResetState reset_state; + XIMHotKeyTriggers *hotkey; + XIMHotKeyState hotkey_state; + + ICPreeditAttributes preedit_attr; /* visuals of preedit area */ + ICStatusAttributes status_attr; /* visuals of status area */ + } XICCoreRec, *XICCore; + + + /* + * an Input Context. Implementations may need to extend this data + * structure to accomodate additional data, state information etc. + */ + typedef struct _XIC { + XICMethods methods; /* method list of this IC */ + XICCoreRec core; /* data of this IC */ + } XICRec; + + /* current Ultrix compiler gets horribly confused */ + #if !defined(NeedFunctionPrototypes) && defined(FUNCPROTO) + #define NeedFunctionPrototypes 1 + #endif + + typedef XLCd (*XLCdLoadProc)( + #if NeedFunctionPrototypes + _Xconst char* + #endif + ); + + _XFUNCPROTOBEGIN + + extern XLCd _XOpenLC( + #if NeedFunctionPrototypes + _Xconst char* /* name */ + #endif + ); + + extern void _XCloseLC( + #if NeedFunctionPrototypes + XLCd /* lcd */ + #endif + ); + + extern XLCd _XlcCurrentLC( + #if NeedFunctionPrototypes + void + #endif + ); + + extern Bool _XlcValidModSyntax( + #if NeedFunctionPrototypes + char* /* mods */, + char** /* valid */ + #endif + ); + + extern char *_XlcDefaultMapModifiers( + #if NeedFunctionPrototypes + XLCd /* lcd */, + char* /* user_mods */, + char* /* prog_mods */ + #endif + ); + + extern void _XIMCompileResourceList( + #if NeedFunctionPrototypes + XIMResourceList /* res */, + unsigned int /* num_res */ + #endif + ); + + extern void _XCopyToArg( + #if NeedFunctionPrototypes + XPointer /* src */, + XPointer* /* dst */, + unsigned int /* size */ + #endif + ); + + extern char ** _XParseBaseFontNameList( + #if NeedFunctionPrototypes + char* /* str */, + int* /* num */ + #endif + ); + + extern XrmMethods _XrmInitParseInfo( + #if NeedFunctionPrototypes + XPointer* /* statep */ + #endif + ); + + extern void _XRegisterFilterByMask( + #if NeedFunctionPrototypes + Display* /* dpy */, + Window /* window */, + unsigned long /* event_mask */, + Bool (*)( + #if NeedNestedPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ + #endif + ) /* filter */, + XPointer /* client_data */ + #endif + ); + + extern void _XRegisterFilterByType( + #if NeedFunctionPrototypes + Display* /* dpy */, + Window /* window */, + int /* start_type */, + int /* end_type */, + Bool (*)( + #if NeedNestedPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ + #endif + ) /* filter */, + XPointer /* client_data */ + #endif + ); + + extern void _XUnregisterFilter( + #if NeedFunctionPrototypes + Display* /* dpy */, + Window /* window */, + Bool (*)( + #if NeedNestedPrototypes + Display* /* display */, + Window /* window */, + XEvent* /* event */, + XPointer /* client_data */ + #endif + ) /* filter */, + XPointer /* client_data */ + #endif + ); + + extern void _XlcCountVaList( + #if NeedFunctionPrototypes + va_list /* var */, + int* /* count_return */ + #endif + ); + + extern void _XlcVaToArgList( + #if NeedFunctionPrototypes + va_list /* var */, + int /* count */, + XlcArgList* /* args_return */ + #endif + ); + + extern void _XlcCompileResourceList( + #if NeedFunctionPrototypes + XlcResourceList /* resources */, + int /* num_resources */ + #endif + ); + + extern char *_XlcGetValues( + #if NeedFunctionPrototypes + XPointer /* base */, + XlcResourceList /* resources */, + int /* num_resources */, + XlcArgList /* args */, + int /* num_args */, + unsigned long /* mask */ + #endif + ); + + extern char *_XlcSetValues( + #if NeedFunctionPrototypes + XPointer /* base */, + XlcResourceList /* resources */, + int /* num_resources */, + XlcArgList /* args */, + int /* num_args */, + unsigned long /* mask */ + #endif + ); + + extern Bool _XlcAddLoader( + #if NeedFunctionPrototypes + XLCdLoadProc /* proc */, + XlcPosition /* position */ + #endif + ); + + extern void _XlcRemoveLoader( + #if NeedFunctionPrototypes + XLCdLoadProc /* proc */ + #endif + ); + + _XFUNCPROTOEND + + #endif /* _XLCINT_H_ */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/Xlibint.h ./unix/CacheLib/Xlibint.h *** ../../tk8.0.5/unix/CacheLib/Xlibint.h Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/Xlibint.h Thu Aug 6 16:48:08 1998 *************** *** 0 **** --- 1,1254 ---- + /* $XFree86: xc/lib/X11/Xlibint.h,v 3.7 1996/12/23 05:59:50 dawes Exp $ */ + /* $XConsortium: Xlibint.h /main/114 1996/10/22 14:24:29 kaleb $ */ + + /* + + Copyright (c) 1984, 1985, 1987, 1989 X Consortium + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the X Consortium shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the X Consortium. + + */ + + /* + * Xlibint.h - Header definition and support file for the internal + * support routines used by the C subroutine interface + * library (Xlib) to the X Window System. + * + * Warning, there be dragons here.... + */ + + #include + + #ifdef WIN32 + #define _XFlush _XFlushIt + #endif + + /* + * If your BytesReadable correctly detects broken connections, then + * you should NOT define XCONN_CHECK_FREQ. + */ + #ifndef XCONN_CHECK_FREQ + #define XCONN_CHECK_FREQ 256 + #endif + + struct _XGC + { + XExtData *ext_data; /* hook for extension to hang data */ + GContext gid; /* protocol ID for graphics context */ + Bool rects; /* boolean: TRUE if clipmask is list of rectangles */ + Bool dashes; /* boolean: TRUE if dash-list is really a list */ + unsigned long dirty;/* cache dirty bits */ + XGCValues values; /* shadow structure of values */ + }; + + struct _XDisplay + { + XExtData *ext_data; /* hook for extension to hang data */ + struct _XFreeFuncs *free_funcs; /* internal free functions */ + int fd; /* Network socket. */ + int conn_checker; /* ugly thing used by _XEventsQueued */ + int proto_major_version;/* maj. version of server's X protocol */ + int proto_minor_version;/* minor version of server's X protocol */ + char *vendor; /* vendor of the server hardware */ + XID resource_base; /* resource ID base */ + XID resource_mask; /* resource ID mask bits */ + XID resource_id; /* allocator current ID */ + int resource_shift; /* allocator shift to correct bits */ + XID (*resource_alloc)( /* allocator function */ + #if NeedFunctionPrototypes + struct _XDisplay* + #endif + ); + int byte_order; /* screen byte order, LSBFirst, MSBFirst */ + int bitmap_unit; /* padding and data requirements */ + int bitmap_pad; /* padding requirements on bitmaps */ + int bitmap_bit_order; /* LeastSignificant or MostSignificant */ + int nformats; /* number of pixmap formats in list */ + ScreenFormat *pixmap_format; /* pixmap format list */ + int vnumber; /* Xlib's X protocol version number. */ + int release; /* release of the server */ + struct _XSQEvent *head, *tail; /* Input event queue. */ + int qlen; /* Length of input event queue */ + unsigned long last_request_read; /* seq number of last event read */ + unsigned long request; /* sequence number of last request. */ + char *last_req; /* beginning of last request, or dummy */ + char *buffer; /* Output buffer starting address. */ + char *bufptr; /* Output buffer index pointer. */ + char *bufmax; /* Output buffer maximum+1 address. */ + unsigned max_request_size; /* maximum number 32 bit words in request*/ + struct _XrmHashBucketRec *db; + int (*synchandler)( /* Synchronization handler */ + #if NeedFunctionPrototypes + struct _XDisplay* + #endif + ); + char *display_name; /* "host:display" string used on this connect*/ + int default_screen; /* default screen for operations */ + int nscreens; /* number of screens on this server*/ + Screen *screens; /* pointer to list of screens */ + unsigned long motion_buffer; /* size of motion buffer */ + unsigned long flags; /* internal connection flags */ + int min_keycode; /* minimum defined keycode */ + int max_keycode; /* maximum defined keycode */ + KeySym *keysyms; /* This server's keysyms */ + XModifierKeymap *modifiermap; /* This server's modifier keymap */ + int keysyms_per_keycode;/* number of rows */ + char *xdefaults; /* contents of defaults from server */ + char *scratch_buffer; /* place to hang scratch buffer */ + unsigned long scratch_length; /* length of scratch buffer */ + int ext_number; /* extension number on this display */ + struct _XExten *ext_procs; /* extensions initialized on this display */ + /* + * the following can be fixed size, as the protocol defines how + * much address space is available. + * While this could be done using the extension vector, there + * may be MANY events processed, so a search through the extension + * list to find the right procedure for each event might be + * expensive if many extensions are being used. + */ + Bool (*event_vec[128])(); /* vector for wire to event */ + Status (*wire_vec[128])(); /* vector for event to wire */ + KeySym lock_meaning; /* for XLookupString */ + struct _XLockInfo *lock; /* multi-thread state, display lock */ + struct _XInternalAsync *async_handlers; /* for internal async */ + unsigned long bigreq_size; /* max size of big requests */ + struct _XLockPtrs *lock_fns; /* pointers to threads functions */ + void (*idlist_alloc)(); /* XID list allocator function */ + /* things above this line should not move, for binary compatibility */ + struct _XKeytrans *key_bindings; /* for XLookupString */ + Font cursor_font; /* for XCreateFontCursor */ + struct _XDisplayAtoms *atoms; /* for XInternAtom */ + unsigned int mode_switch; /* keyboard group modifiers */ + unsigned int num_lock; /* keyboard numlock modifiers */ + struct _XContextDB *context_db; /* context database */ + Bool (**error_vec)(); /* vector for wire to error */ + /* + * Xcms information + */ + struct { + XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */ + XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */ + XPointer perVisualIntensityMaps; + /* linked list of XcmsIntensityMap */ + } cms; + struct _XIMFilter *im_filters; + struct _XSQEvent *qfree; /* unallocated event queue elements */ + unsigned long next_event_serial_num; /* inserted into next queue elt */ + struct _XExten *flushes; /* Flush hooks */ + struct _XConnectionInfo *im_fd_info; /* _XRegisterInternalConnection */ + int im_fd_length; /* number of im_fd_info */ + struct _XConnWatchInfo *conn_watchers; /* XAddConnectionWatch */ + int watcher_count; /* number of conn_watchers */ + XPointer filedes; /* struct pollfd cache for _XWaitForReadable */ + int (*savedsynchandler)(); /* user synchandler when Xlib usurps */ + XID resource_max; /* allocator max ID */ + int xcmisc_opcode; /* major opcode for XC-MISC */ + struct _XkbInfoRec *xkb_info; /* XKB info */ + struct _XtransConnInfo *trans_conn; /* transport connection object */ + }; + + #define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) + + /* + * define the following if you want the Data macro to be a procedure instead + */ + #ifdef CRAY + #define DataRoutineIsProcedure + #endif /* CRAY */ + + #ifndef _XEVENT_ + /* + * _QEvent datatype for use in input queueing. + */ + typedef struct _XSQEvent + { + struct _XSQEvent *next; + XEvent event; + unsigned long qserial_num; /* so multi-threaded code can find new ones */ + } _XQEvent; + #endif + + #ifdef XTHREADS /* for xReply */ + #define NEED_REPLIES + #endif + + #if NeedFunctionPrototypes /* prototypes require event type definitions */ + #define NEED_EVENTS + #define NEED_REPLIES + #endif + #include + #ifdef __sgi + #define _SGI_MP_SOURCE /* turn this on to get MP safe errno */ + #endif + #include + #define _XBCOPYFUNC _Xbcopy + #include + #include + + /* Utek leaves kernel macros around in include files (bleah) */ + #ifdef dirty + #undef dirty + #endif + + #ifndef X_NOT_STDC_ENV + #include + #include + #else + char *malloc(), *realloc(), *calloc(); + void exit(); + #ifdef SYSV + #include + #else + #include + #endif + #endif + + /* + * The following definitions can be used for locking requests in multi-threaded + * address spaces. + */ + #ifdef XTHREADS + /* Author: Stephen Gildea, MIT X Consortium + * + * declarations for C Threads locking + */ + + #include + + struct _XLockPtrs { + /* used by all, including extensions; do not move */ + void (*lock_display)(); + void (*unlock_display)(); + }; + + typedef struct _LockInfoRec *LockInfoPtr; + + #if defined(WIN32) && !defined(_XLIBINT_) + #define _XCreateMutex_fn (*_XCreateMutex_fn_p) + #define _XFreeMutex_fn (*_XFreeMutex_fn_p) + #define _XLockMutex_fn (*_XLockMutex_fn_p) + #define _XUnlockMutex_fn (*_XUnlockMutex_fn_p) + #define _Xglobal_lock (*_Xglobal_lock_p) + #endif + + /* in XlibInt.c */ + extern void (*_XCreateMutex_fn)( + #if NeedFunctionPrototypes + LockInfoPtr /* lock */ + #endif + ); + extern void (*_XFreeMutex_fn)( + #if NeedFunctionPrototypes + LockInfoPtr /* lock */ + #endif + ); + extern void (*_XLockMutex_fn)( + #if NeedFunctionPrototypes + LockInfoPtr /* lock */ + #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + , char * /* file */ + , int /* line */ + #endif + #endif + ); + extern void (*_XUnlockMutex_fn)( + #if NeedFunctionPrototypes + LockInfoPtr /* lock */ + #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + , char * /* file */ + , int /* line */ + #endif + #endif + ); + + extern LockInfoPtr _Xglobal_lock; + + #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) + #define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)((d),__FILE__,__LINE__) + #define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)((d),__FILE__,__LINE__) + #define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock,__FILE__,__LINE__) + #define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock,__FILE__,__LINE__) + #else + /* used everywhere, so must be fast if not using threads */ + #define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)(d) + #define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)(d) + #define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock) + #define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock) + #endif + #define _XCreateMutex(lock) if (_XCreateMutex_fn) (*_XCreateMutex_fn)(lock); + #define _XFreeMutex(lock) if (_XFreeMutex_fn) (*_XFreeMutex_fn)(lock); + + #else /* XTHREADS */ + #define LockDisplay(dis) + #define _XLockMutex(lock) + #define _XUnlockMutex(lock) + #define UnlockDisplay(dis) + #define _XCreateMutex(lock) + #define _XFreeMutex(lock) + #endif + + #define Xfree(ptr) free((ptr)) + + /* + * Note that some machines do not return a valid pointer for malloc(0), in + * which case we provide an alternate under the control of the + * define MALLOC_0_RETURNS_NULL. This is necessary because some + * Xlib code expects malloc(0) to return a valid pointer to storage. + */ + #ifdef MALLOC_0_RETURNS_NULL + + # define Xmalloc(size) malloc(((size) == 0 ? 1 : (size))) + # define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size))) + # define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize)) + + #else + + # define Xmalloc(size) malloc((size)) + # define Xrealloc(ptr, size) realloc((ptr), (size)) + # define Xcalloc(nelem, elsize) calloc((nelem), (elsize)) + + #endif + + #ifndef NULL + #define NULL 0 + #endif + #define LOCKED 1 + #define UNLOCKED 0 + + #ifdef X_NOT_STDC_ENV + extern int errno; /* Internal system error number. */ + #endif + + #ifndef BUFSIZE + #define BUFSIZE 2048 /* X output buffer size. */ + #endif + #ifndef PTSPERBATCH + #define PTSPERBATCH 1024 /* point batching */ + #endif + #ifndef WLNSPERBATCH + #define WLNSPERBATCH 50 /* wide line batching */ + #endif + #ifndef ZLNSPERBATCH + #define ZLNSPERBATCH 1024 /* thin line batching */ + #endif + #ifndef WRCTSPERBATCH + #define WRCTSPERBATCH 10 /* wide line rectangle batching */ + #endif + #ifndef ZRCTSPERBATCH + #define ZRCTSPERBATCH 256 /* thin line rectangle batching */ + #endif + #ifndef FRCTSPERBATCH + #define FRCTSPERBATCH 256 /* filled rectangle batching */ + #endif + #ifndef FARCSPERBATCH + #define FARCSPERBATCH 256 /* filled arc batching */ + #endif + #ifndef CURSORFONT + #define CURSORFONT "cursor" /* standard cursor fonts */ + #endif + + /* + * Display flags + */ + #define XlibDisplayIOError (1L << 0) + #define XlibDisplayClosing (1L << 1) + #define XlibDisplayNoXkb (1L << 2) + #define XlibDisplayPrivSync (1L << 3) + #define XlibDisplayProcConni (1L << 4) /* in _XProcessInternalConnection */ + #define XlibDisplayReadEvents (1L << 5) /* in _XReadEvents */ + #define XlibDisplayReply (1L << 5) /* in _XReply */ + #define XlibDisplayWriting (1L << 6) /* in _XFlushInt, _XSend */ + + /* + * X Protocol packetizing macros. + */ + + /* Need to start requests on 64 bit word boundaries + * on a CRAY computer so add a NoOp (127) if needed. + * A character pointer on a CRAY computer will be non-zero + * after shifting right 61 bits of it is not pointing to + * a word boundary. + */ + #ifdef WORD64 + #define WORD64ALIGN if ((long)dpy->bufptr >> 61) {\ + dpy->last_req = dpy->bufptr;\ + *(dpy->bufptr) = X_NoOperation;\ + *(dpy->bufptr+1) = 0;\ + *(dpy->bufptr+2) = 0;\ + *(dpy->bufptr+3) = 1;\ + dpy->request++;\ + dpy->bufptr += 4;\ + } + #else /* else does not require alignment on 64-bit boundaries */ + #define WORD64ALIGN + #endif /* WORD64 */ + + + /* + * GetReq - Get the next available X request packet in the buffer and + * return it. + * + * "name" is the name of the request, e.g. CreatePixmap, OpenFont, etc. + * "req" is the name of the request pointer. + * + */ + + #if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) + #define GetReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = (SIZEOF(x##name##Req))>>2;\ + dpy->bufptr += SIZEOF(x##name##Req);\ + dpy->request++ + + #else /* non-ANSI C uses empty comment instead of "##" for token concatenation */ + #define GetReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = (SIZEOF(x/**/name/**/Req))>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req);\ + dpy->request++ + #endif + + /* GetReqExtra is the same as GetReq, but allocates "n" additional + bytes after the request. "n" must be a multiple of 4! */ + + #if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) + #define GetReqExtra(name, n, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x##name##Req) + n) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = (SIZEOF(x##name##Req) + n)>>2;\ + dpy->bufptr += SIZEOF(x##name##Req) + n;\ + dpy->request++ + #else + #define GetReqExtra(name, n, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(x/**/name/**/Req) + n) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = (SIZEOF(x/**/name/**/Req) + n)>>2;\ + dpy->bufptr += SIZEOF(x/**/name/**/Req) + n;\ + dpy->request++ + #endif + + + /* + * GetResReq is for those requests that have a resource ID + * (Window, Pixmap, GContext, etc.) as their single argument. + * "rid" is the name of the resource. + */ + + #if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) + #define GetResReq(name, rid, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = 2;\ + req->id = (rid);\ + dpy->bufptr += SIZEOF(xResourceReq);\ + dpy->request++ + #else + #define GetResReq(name, rid, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xResourceReq)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xResourceReq *) (dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = 2;\ + req->id = (rid);\ + dpy->bufptr += SIZEOF(xResourceReq);\ + dpy->request++ + #endif + + /* + * GetEmptyReq is for those requests that have no arguments + * at all. + */ + #if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) + #define GetEmptyReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xReq *) (dpy->last_req = dpy->bufptr);\ + req->reqType = X_##name;\ + req->length = 1;\ + dpy->bufptr += SIZEOF(xReq);\ + dpy->request++ + #else + #define GetEmptyReq(name, req) \ + WORD64ALIGN\ + if ((dpy->bufptr + SIZEOF(xReq)) > dpy->bufmax)\ + _XFlush(dpy);\ + req = (xReq *) (dpy->last_req = dpy->bufptr);\ + req->reqType = X_/**/name;\ + req->length = 1;\ + dpy->bufptr += SIZEOF(xReq);\ + dpy->request++ + #endif + + #ifdef WORD64 + #define MakeBigReq(req,n) \ + { \ + char _BRdat[4]; \ + unsigned long _BRlen = req->length - 1; \ + req->length = 0; \ + memcpy(_BRdat, ((char *)req) + (_BRlen << 2), 4); \ + memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ + memcpy(((char *)req) + 4, _BRdat, 4); \ + Data32(dpy, (long *)&_BRdat, 4); \ + } + #else + #define MakeBigReq(req,n) \ + { \ + CARD32 _BRdat; \ + CARD32 _BRlen = req->length - 1; \ + req->length = 0; \ + _BRdat = ((CARD32 *)req)[_BRlen]; \ + memmove(((char *)req) + 8, ((char *)req) + 4, _BRlen << 2); \ + ((CARD32 *)req)[1] = _BRlen + n + 2; \ + Data32(dpy, &_BRdat, 4); \ + } + #endif + + #define SetReqLen(req,n,badlen) \ + if ((req->length + n) > (unsigned)65535) { \ + if (dpy->bigreq_size) { \ + MakeBigReq(req,n) \ + } else { \ + n = badlen; \ + req->length += n; \ + } \ + } else \ + req->length += n + + #define SyncHandle() \ + if (dpy->synchandler) (*dpy->synchandler)(dpy) + + extern void _XFlushGCCache(); + #define FlushGC(dpy, gc) \ + if ((gc)->dirty) _XFlushGCCache((dpy), (gc)) + /* + * Data - Place data in the buffer and pad the end to provide + * 32 bit word alignment. Transmit if the buffer fills. + * + * "dpy" is a pointer to a Display. + * "data" is a pinter to a data buffer. + * "len" is the length of the data buffer. + */ + #ifndef DataRoutineIsProcedure + #define Data(dpy, data, len) \ + if (dpy->bufptr + (len) <= dpy->bufmax) {\ + memcpy(dpy->bufptr, data, (int)len);\ + dpy->bufptr += ((len) + 3) & ~3;\ + } else\ + _XSend(dpy, data, len) + #endif /* DataRoutineIsProcedure */ + + + /* Allocate bytes from the buffer. No padding is done, so if + * the length is not a multiple of 4, the caller must be + * careful to leave the buffer aligned after sending the + * current request. + * + * "type" is the type of the pointer being assigned to. + * "ptr" is the pointer being assigned to. + * "n" is the number of bytes to allocate. + * + * Example: + * xTextElt *elt; + * BufAlloc (xTextElt *, elt, nbytes) + */ + + #define BufAlloc(type, ptr, n) \ + if (dpy->bufptr + (n) > dpy->bufmax) \ + _XFlush (dpy); \ + ptr = (type) dpy->bufptr; \ + dpy->bufptr += (n); + + #ifdef WORD64 + #define Data16(dpy, data, len) _XData16(dpy, (short *)data, len) + #define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) + #else + #define Data16(dpy, data, len) Data((dpy), (char *)(data), (len)) + #define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len)) + #define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len)) + #ifdef LONG64 + #define Data32(dpy, data, len) _XData32(dpy, (long *)data, len) + #else + #define Data32(dpy, data, len) Data((dpy), (char *)(data), (len)) + #define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len)) + #endif + #endif /* not WORD64 */ + + #define PackData16(dpy,data,len) Data16 (dpy, data, len) + #define PackData32(dpy,data,len) Data32 (dpy, data, len) + + /* Xlib manual is bogus */ + #define PackData(dpy,data,len) PackData16 (dpy, data, len) + + #define min(a,b) (((a) < (b)) ? (a) : (b)) + #define max(a,b) (((a) > (b)) ? (a) : (b)) + + #define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ + (((cs)->rbearing|(cs)->lbearing| \ + (cs)->ascent|(cs)->descent) == 0)) + + /* + * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit + * character. If the character is in the column and exists, then return the + * appropriate metrics (note that fonts with common per-character metrics will + * return min_bounds). If none of these hold true, try again with the default + * char. + */ + #define CI_GET_CHAR_INFO_1D(fs,col,def,cs) \ + { \ + cs = def; \ + if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ + } + + #define CI_GET_DEFAULT_INFO_1D(fs,cs) \ + CI_GET_CHAR_INFO_1D (fs, fs->default_char, NULL, cs) + + + + /* + * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and + * column. This is used for fonts that have more than row zero. + */ + #define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \ + { \ + cs = def; \ + if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ + col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ + if (fs->per_char == NULL) { \ + cs = &fs->min_bounds; \ + } else { \ + cs = &fs->per_char[((row - fs->min_byte1) * \ + (fs->max_char_or_byte2 - \ + fs->min_char_or_byte2 + 1)) + \ + (col - fs->min_char_or_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ + } + + #define CI_GET_DEFAULT_INFO_2D(fs,cs) \ + { \ + unsigned int r = (fs->default_char >> 8); \ + unsigned int c = (fs->default_char & 0xff); \ + CI_GET_CHAR_INFO_2D (fs, r, c, NULL, cs); \ + } + + + #ifdef MUSTCOPY + + /* for when 32-bit alignment is not good enough */ + #define OneDataCard32(dpy,dstaddr,srcvar) \ + { dpy->bufptr -= 4; Data32 (dpy, (char *) &(srcvar), 4); } + + #else + + /* srcvar must be a variable for large architecture version */ + #define OneDataCard32(dpy,dstaddr,srcvar) \ + { *(CARD32 *)(dstaddr) = (srcvar); } + + #endif /* MUSTCOPY */ + + typedef struct _XInternalAsync { + struct _XInternalAsync *next; + /* + * handler arguments: + * rep is the generic reply that caused this handler + * to be invoked. It must also be passed to _XGetAsyncReply. + * buf and len are opaque values that must be passed to + * _XGetAsyncReply or _XGetAsyncData. + * data is the closure stored in this struct. + * The handler returns True iff it handled this reply. + */ + Bool (*handler)( + #if NeedNestedPrototypes + Display* /* dpy */, + xReply* /* rep */, + char* /* buf */, + int /* len */, + XPointer /* data */ + #endif + ); + XPointer data; + } _XAsyncHandler; + + typedef struct _XAsyncEState { + unsigned long min_sequence_number; + unsigned long max_sequence_number; + unsigned char error_code; + unsigned char major_opcode; + unsigned short minor_opcode; + unsigned char last_error_received; + int error_count; + } _XAsyncErrorState; + + extern void _XDeqAsyncHandler(); + #define DeqAsyncHandler(dpy,handler) { \ + if (dpy->async_handlers == (handler)) \ + dpy->async_handlers = (handler)->next; \ + else \ + _XDeqAsyncHandler(dpy, handler); \ + } + + /* + * This structure is private to the library. + */ + typedef struct _XFreeFuncs { + void (*atoms)(); /* _XFreeAtomTable */ + int (*modifiermap)(); /* XFreeModifierMap */ + void (*key_bindings)(); /* _XFreeKeyBindings */ + void (*context_db)(); /* _XFreeContextDB */ + void (*defaultCCCs)(); /* _XcmsFreeDefaultCCCs */ + void (*clientCmaps)(); /* _XcmsFreeClientCmaps */ + void (*intensityMaps)(); /* _XcmsFreeIntensityMaps */ + void (*im_filters)(); /* _XFreeIMFilters */ + void (*xkb)(); /* _XkbFreeInfo */ + } _XFreeFuncRec; + + /* + * This structure is private to the library. + */ + typedef struct _XExten { /* private to extension mechanism */ + struct _XExten *next; /* next in list */ + XExtCodes codes; /* public information, all extension told */ + int (*create_GC)(); /* routine to call when GC created */ + int (*copy_GC)(); /* routine to call when GC copied */ + int (*flush_GC)(); /* routine to call when GC flushed */ + int (*free_GC)(); /* routine to call when GC freed */ + int (*create_Font)(); /* routine to call when Font created */ + int (*free_Font)(); /* routine to call when Font freed */ + int (*close_display)(); /* routine to call when connection closed */ + int (*error)(); /* who to call when an error occurs */ + char *(*error_string)(); /* routine to supply error string */ + char *name; /* name of this extension */ + void (*error_values)(); /* routine to supply error values */ + void (*before_flush)(); /* routine to call when sending data */ + struct _XExten *next_flush; /* next in list of those with flushes */ + } _XExtension; + + /* extension hooks */ + + _XFUNCPROTOBEGIN + + #ifdef DataRoutineIsProcedure + extern void Data(); + #endif + extern int _XError( + #if NeedFunctionPrototypes + Display* /* dpy */, + xError* /* rep */ + #endif + ); + extern int _XIOError( + #if NeedFunctionPrototypes + Display* /* dpy */ + #endif + ); + extern int (*_XIOErrorFunction)( + #if NeedNestedPrototypes + Display* /* dpy */ + #endif + ); + extern int (*_XErrorFunction)( + #if NeedNestedPrototypes + Display* /* dpy */, + XErrorEvent* /* error_event */ + #endif + ); + extern void _XEatData( + #if NeedFunctionPrototypes + Display* /* dpy */, + unsigned long /* n */ + #endif + ); + extern char *_XAllocScratch( + #if NeedFunctionPrototypes + Display* /* dpy */, + unsigned long /* nbytes */ + #endif + ); + extern char *_XAllocTemp( + #if NeedFunctionPrototypes + Display* /* dpy */, + unsigned long /* nbytes */ + #endif + ); + extern void _XFreeTemp( + #if NeedFunctionPrototypes + Display* /* dpy */, + char* /* buf */, + unsigned long /* nbytes */ + #endif + ); + extern Visual *_XVIDtoVisual( + #if NeedFunctionPrototypes + Display* /* dpy */, + VisualID /* id */ + #endif + ); + extern unsigned long _XSetLastRequestRead( + #if NeedFunctionPrototypes + Display* /* dpy */, + xGenericReply* /* rep */ + #endif + ); + extern int _XGetHostname( + #if NeedFunctionPrototypes + char* /* buf */, + int /* maxlen */ + #endif + ); + extern Screen *_XScreenOfWindow( + #if NeedFunctionPrototypes + Display* /* dpy */, + Window /* w */ + #endif + ); + extern Bool _XAsyncErrorHandler( + #if NeedFunctionPrototypes + Display* /* dpy */, + xReply* /* rep */, + char* /* buf */, + int /* len */, + XPointer /* data */ + #endif + ); + extern char *_XGetAsyncReply( + #if NeedFunctionPrototypes + Display* /* dpy */, + char* /* replbuf */, + xReply* /* rep */, + char* /* buf */, + int /* len */, + int /* extra */, + Bool /* discard */ + #endif + ); + extern void _XFlush( + #if NeedFunctionPrototypes + Display* /* dpy */ + #endif + ); + extern int _XEventsQueued( + #if NeedFunctionPrototypes + Display* /* dpy */, + int /* mode */ + #endif + ); + extern void _XReadEvents( + #if NeedFunctionPrototypes + Display* /* dpy */ + #endif + ); + extern int _XRead( + #if NeedFunctionPrototypes + Display* /* dpy */, + char* /* data */, + long /* size */ + #endif + ); + extern void _XReadPad( + #if NeedFunctionPrototypes + Display* /* dpy */, + char* /* data */, + long /* size */ + #endif + ); + extern void _XSend( + #if NeedFunctionPrototypes + Display* /* dpy */, + _Xconst char* /* data */, + long /* size */ + #endif + ); + extern Status _XReply( + #if NeedFunctionPrototypes + Display* /* dpy */, + xReply* /* rep */, + int /* extra */, + Bool /* discard */ + #endif + ); + extern void _XEnq( + #if NeedFunctionPrototypes + Display* /* dpy */, + xEvent* /* event */ + #endif + ); + extern void _XDeq( + #if NeedFunctionPrototypes + Display* /* dpy */, + _XQEvent* /* prev */, + _XQEvent* /* qelt */ + #endif + ); + + extern int (*XESetCreateGC( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, GC, XExtCodes* + #endif + ); + + extern int (*XESetCopyGC( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, GC, XExtCodes* + #endif + ); + + extern int (*XESetFlushGC( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, GC, XExtCodes* + #endif + ); + + extern int (*XESetFreeGC( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, GC, XExtCodes* + #endif + ); + + extern int (*XESetCreateFont( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XFontStruct*, XExtCodes* + #endif + ); + + extern int (*XESetFreeFont( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XFontStruct*, XExtCodes* + #endif + ); + + extern int (*XESetCloseDisplay( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XExtCodes* /* codes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XExtCodes* + #endif + ); + + extern int (*XESetError( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + int (*) ( + #if NeedNestedPrototypes + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, xError*, XExtCodes*, int* + #endif + ); + + extern char* (*XESetErrorString( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + char* (*) ( + #if NeedNestedPrototypes + Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, int, XExtCodes*, char*, int + #endif + ); + + extern void (*XESetPrintErrorValues ( + #if NeedFunctionPrototypes + Display* /* display */, + int /* extension */, + void (*)( + #if NeedNestedPrototypes + Display* /* display */, + XErrorEvent* /* ev */, + void* /* fp */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XErrorEvent*, void* + #endif + ); + + extern Bool (*XESetWireToEvent( + #if NeedFunctionPrototypes + Display* /* display */, + int /* event_number */, + Bool (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XEvent*, xEvent* + #endif + ); + + extern Status (*XESetEventToWire( + #if NeedFunctionPrototypes + Display* /* display */, + int /* event_number */, + Status (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XEvent*, xEvent* + #endif + ); + + extern Bool (*XESetWireToError( + #if NeedFunctionPrototypes + Display* /* display */, + int /* error_number */, + Bool (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XErrorEvent* /* he */, + xError* /* we */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XErrorEvent*, xError* + #endif + ); + + extern void (*XESetBeforeFlush( + #if NeedFunctionPrototypes + Display* /* display */, + int /* error_number */, + void (*) ( + #if NeedNestedPrototypes + Display* /* display */, + XExtCodes* /* codes */, + char* /* data */, + long /* len */ + #endif + ) /* proc */ + #endif + ))( + #if NeedNestedPrototypes + Display*, XExtCodes*, char*, long + #endif + ); + + /* internal connections for IMs */ + + typedef void (*_XInternalConnectionProc)( + #if NeedFunctionPrototypes + Display* /* dpy */, + int /* fd */, + XPointer /* call_data */ + #endif + ); + + + extern Status _XRegisterInternalConnection( + #if NeedFunctionPrototypes + Display* /* dpy */, + int /* fd */, + _XInternalConnectionProc /* callback */, + XPointer /* call_data */ + #endif + ); + + extern void _XUnregisterInternalConnection( + #if NeedFunctionPrototypes + Display* /* dpy */, + int /* fd */ + #endif + ); + + /* Display structure has pointers to these */ + + struct _XConnectionInfo { /* info from _XRegisterInternalConnection */ + int fd; + _XInternalConnectionProc read_callback; + XPointer call_data; + XPointer *watch_data; /* set/used by XConnectionWatchProc */ + struct _XConnectionInfo *next; + }; + + struct _XConnWatchInfo { /* info from XAddConnectionWatch */ + XConnectionWatchProc fn; + XPointer client_data; + struct _XConnWatchInfo *next; + }; + + #ifdef __EMX__ + extern char* __XOS2RedirRoot( + #if NeedFunctionPrototypes + char* + #endif + ); + #endif + + extern int _XTextHeight( + #if NeedFunctionPrototypes + XFontStruct* /* font_struct */, + _Xconst char* /* string */, + int /* count */ + #endif + ); + + extern int _XTextHeight16( + #if NeedFunctionPrototypes + XFontStruct* /* font_struct */, + _Xconst XChar2b* /* string */, + int /* count */ + #endif + ); + + _XFUNCPROTOEND diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/XomGeneric.h ./unix/CacheLib/XomGeneric.h *** ../../tk8.0.5/unix/CacheLib/XomGeneric.h Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/XomGeneric.h Thu Aug 6 16:48:09 1998 *************** *** 0 **** --- 1,181 ---- + /* $XConsortium: XomGeneric.h /main/4 1996/12/05 10:40:15 swick $ */ + /* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + /* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + + #ifndef _XOMGENERIC_H_ + #define _XOMGENERIC_H_ + + #include "XlcPublic.h" + + #define XOM_GENERIC(om) (&((XOMGeneric) om)->gen) + #define XOC_GENERIC(font_set) (&((XOCGeneric) font_set)->gen) + + /* For VW/UDC */ + typedef struct _CodeRangeRec { + unsigned long start; + unsigned long end; + unsigned long dmy1; + unsigned long dmy2; + } CodeRangeRec, *CodeRange; + + typedef struct _VRotateRec { + char *charset_name; /* Charset name */ + XlcSide side; /* Encoding side */ + int num_cr; + CodeRange code_range; + char *xlfd_name; + XFontStruct *font; + } VRotateRec, *VRotate; + + typedef enum { + XOMMultiByte, + XOMWideChar + } XOMTextType; + + typedef struct _FontDataRec { + char *name; + XlcSide side; + /* For VW/UDC */ + int scopes_num; + FontScope scopes; + char *xlfd_name; + XFontStruct *font; + } FontDataRec, *FontData; + + #define VROTATE_NONE 0 + #define VROTATE_PART 1 + #define VROTATE_ALL 2 + + typedef struct _OMDataRec { + int charset_count; + XlcCharSet *charset_list; + int font_data_count; + FontData font_data; + /* For VW/UDC */ + int substitute_num; + FontData substitute; + /* Vertical Writing */ + int vmap_num; + FontData vmap; + int vrotate_type; + int vrotate_num; + CodeRange vrotate; + } OMDataRec, *OMData; + + typedef struct _XOMGenericPart { + int data_num; + OMData data; + Bool on_demand_loading; + char *object_name; + } XOMGenericPart; + + typedef struct _XOMGenericRec { + XOMMethods methods; + XOMCoreRec core; + XOMGenericPart gen; + } XOMGenericRec, *XOMGeneric; + + /* + * XOC dependent data + */ + + typedef struct _FontSetRec { + int id; + int charset_count; + XlcCharSet *charset_list; + int font_data_count; + FontData font_data; + char *font_name; + XFontStruct *info; + XFontStruct *font; + XlcSide side; + Bool is_xchar2b; + /* For VW/UDC */ + int substitute_num; + FontData substitute; + /* Vertical Writing */ + int vpart_initialize; + int vmap_num; + FontData vmap; + int vrotate_num; + VRotate vrotate; + } FontSetRec, *FontSet; + + typedef struct _XOCGenericPart { + XlcConv mbs_to_cs; + XlcConv wcs_to_cs; + int font_set_num; + FontSet font_set; + } XOCGenericPart; + + typedef struct _XOCGenericRec { + XOCMethods methods; + XOCCoreRec core; + XOCGenericPart gen; + } XOCGenericRec, *XOCGeneric; + + _XFUNCPROTOBEGIN + + extern XOM _XomGenericOpenOM( + #if NeedFunctionPrototypes + XLCd /* lcd */, + Display* /* dpy */, + XrmDatabase /* rdb */, + _Xconst char* /* res_name */, + _Xconst char* /* res_class */ + #endif + ); + + extern XlcConv _XomInitConverter( + #if NeedFunctionPrototypes + XOC /* oc */, + XOMTextType /* type */ + #endif + ); + + extern int _XomConvert( + #if NeedFunctionPrototypes + XOC /* oc */, + XlcConv /* conv */, + XPointer* /* from */, + int* /* from_left */, + XPointer* /* to */, + int* /* to_left */, + XPointer* /* args */, + int /* num_args */ + #endif + ); + + _XFUNCPROTOEND + + #endif /* _XOMGENERIC_H_ */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/Xvarargs.h ./unix/CacheLib/Xvarargs.h *** ../../tk8.0.5/unix/CacheLib/Xvarargs.h Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/Xvarargs.h Thu Aug 6 16:48:09 1998 *************** *** 0 **** --- 1,72 ---- + /* $XConsortium: Xvarargs.h,v 1.4 94/04/17 20:21:57 rws Exp $ */ + /* + + Copyright (c) 1985, 1986, 1987, 1988, 1989 X Consortium + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the X Consortium shall + not be used in advertising or otherwise to promote the sale, use or + other dealings in this Software without prior written authorization + from the X Consortium. + + */ + + #ifndef _XVARARGS_H_ + #define _XVARARGS_H_ + + #ifdef __HIGHC__ + #ifndef _STDARG_H + #define _STDARG_H + + typedef char *va_list; + + /* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + + #define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + + #define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) + + #define va_end(AP) + + #define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + + #endif /* _STDARG_H */ + + #define Va_start(a,b) va_start(a,b) + + #else /* !__HIGHC__ */ + + #if NeedVarargsPrototypes + # include + # define Va_start(a,b) va_start(a,b) + #else + # include + # define Va_start(a,b) va_start(a) + #endif + + #endif /* __HIGHC__ */ + + #endif /* _XVARARGS_H_ */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/chkImEv.c ./unix/CacheLib/chkImEv.c *** ../../tk8.0.5/unix/CacheLib/chkImEv.c Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/chkImEv.c Sat May 1 18:32:04 1999 *************** *** 0 **** --- 1,71 ---- + #ifdef XIM_IMPROVE + + static char *imOnThSpot = "Tk_Use_Im_On_The_Spot"; + + #include "Xlibint.h" + #include "Xlcint.h" + + #ifdef TK_USE_ON_THE_SPOT + + Bool + TkpIMIsEventFilterd(ev) + XEvent *ev; + { + extern long _Xevent_to_mask[]; + XFilterEventList p; + Window win; + unsigned long mask; + + win = ev->xany.window; + if (ev->type >= LASTEvent) { + mask = 0L; + } else { + mask = _Xevent_to_mask[ev->type]; + } + + for (p = ev->xany.display->im_filters; p != NULL; p = p->next) { + if (win == p->window) { + if ((mask & p->event_mask) || + (ev->type >= p->start_type && ev->type <= p->end_type)) { + return True; + } + } + } + return False; + } + #else + + static char *imOnThSpot = "Tk_Doesn't_Use_Im_On_The_Spot"; + + Bool + TkpIMIsEventFilterd(ev) + XEvent *ev; + { + return False; + } + #endif /* TK_USE_ON_THE_SPOT */ + + static Bool + IsNotIMEvent(dpy, ev0, ptr) + Display *dpy; + XEvent *ev0; + XPointer ptr; + { + if (TkpIMIsEventFilterd(ev0) == True) { + return False; + } else { + return True; + } + } + + + Bool + TkpIMGetNonIMEventFromXQueue(dpy, evPtr) + Display *dpy; + XEvent *evPtr; + { + return XCheckIfEvent(dpy, evPtr, IsNotIMEvent, NULL); + } + #else + static char *imOnTheSpot = "Tk_XIM_Not_Improved"; + #endif /* XIM_IMPROVE */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/CacheLib/omGeneric.c ./unix/CacheLib/omGeneric.c *** ../../tk8.0.5/unix/CacheLib/omGeneric.c Thu Jan 1 09:00:00 1970 --- ./unix/CacheLib/omGeneric.c Wed Aug 12 22:22:58 1998 *************** *** 0 **** --- 1,1981 ---- + /* $TOG: omGeneric.c /main/22 1997/07/17 21:49:06 kaleb $ */ + /* + * Copyright 1992, 1993 by TOSHIBA Corp. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of TOSHIBA not be used in advertising + * or publicity pertaining to distribution of the software without specific, + * written prior permission. TOSHIBA make no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * TOSHIBA DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL + * TOSHIBA BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR + * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, + * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * + * Author: Katsuhisa Yano TOSHIBA Corp. + * mopi@osa.ilab.toshiba.co.jp + */ + /* + * Copyright 1995 by FUJITSU LIMITED + * This is source code modified by FUJITSU LIMITED under the Joint + * Development Agreement for the CDE/Motif PST. + * + * Modifier: Takanori Tateno FUJITSU LIMITED + * + */ + /* $XFree86: xc/lib/X11/omGeneric.c,v 3.5.2.2 1997/07/19 04:59:11 dawes Exp $ */ + + #ifdef USE_MODIFIED_XOM + static int Tk_Use_Modified_XOM = 1; + #include "Xlibint.h" + #include "XomGeneric.h" + #include + #include + #include + #include + #include + + #define MAXFONTS 100 + #define PIXEL_SIZE_FIELD 7 + #define POINT_SIZE_FIELD 8 + #define CHARSET_ENCODING_FIELD 14 + + extern int _XmbDefaultTextEscapement(), _XwcDefaultTextEscapement(); + extern int _XmbDefaultTextExtents(), _XwcDefaultTextExtents(); + extern Status _XmbDefaultTextPerCharExtents(), _XwcDefaultTextPerCharExtents(); + extern int _XmbDefaultDrawString(), _XwcDefaultDrawString(); + extern void _XmbDefaultDrawImageString(), _XwcDefaultDrawImageString(); + + extern int _XmbGenericTextEscapement(), _XwcGenericTextEscapement(); + extern int _XmbGenericTextExtents(), _XwcGenericTextExtents(); + extern Status _XmbGenericTextPerCharExtents(), _XwcGenericTextPerCharExtents(); + extern int _XmbGenericDrawString(), _XwcGenericDrawString(); + extern void _XmbGenericDrawImageString(), _XwcGenericDrawImageString(); + + extern void _XlcDbg_printValue(); + + /* For VW/UDC start */ + + static FontData + init_fontdata(font_data, font_data_count) + FontData font_data; + int font_data_count; + { + FontData fd; + int i; + + fd = (FontData)Xmalloc(sizeof(FontDataRec) * font_data_count); + if(fd == (FontData) NULL) + return False; + + memset(fd, 0x00, sizeof(FontData) * font_data_count); + for(i = 0 ; i < font_data_count ; i++) + fd[i] = font_data[i]; + + return fd; + } + + static VRotate + init_vrotate(font_data, font_data_count, type, code_range, code_range_num) + FontData font_data; + int font_data_count; + int type; + CodeRange code_range; + int code_range_num; + { + VRotate vrotate; + int i; + + if(type == VROTATE_NONE) + return (VRotate)NULL; + + vrotate = (VRotate)Xmalloc(sizeof(VRotateRec) * font_data_count); + if(vrotate == (VRotate) NULL) + return False; + + memset(vrotate, 0x00, sizeof(VRotateRec) * font_data_count); + for(i = 0 ; i < font_data_count ; i++) { + vrotate[i].charset_name = font_data[i].name; + vrotate[i].side = font_data[i].side; + if(type == VROTATE_PART) { + vrotate[i].num_cr = code_range_num; + vrotate[i].code_range = code_range; + } + } + + return vrotate; + } + + static Bool + init_fontset(oc) + XOC oc; + { + XOCGenericPart *gen; + FontSet font_set; + OMData data; + int count; + + count = XOM_GENERIC(oc->core.om)->data_num; + data = XOM_GENERIC(oc->core.om)->data; + + font_set = (FontSet) Xmalloc(sizeof(FontSetRec) * count); + if (font_set == NULL) + return False; + memset((char *) font_set, 0x00, sizeof(FontSetRec) * count); + + gen = XOC_GENERIC(oc); + gen->font_set_num = count; + gen->font_set = font_set; + + for ( ; count-- > 0; data++, font_set++) { + font_set->charset_count = data->charset_count; + font_set->charset_list = data->charset_list; + + if((font_set->font_data = init_fontdata(data->font_data, + data->font_data_count)) == NULL) + goto err; + font_set->font_data_count = data->font_data_count; + if((font_set->substitute = init_fontdata(data->substitute, + data->substitute_num)) == NULL) + goto err; + font_set->substitute_num = data->substitute_num; + if((font_set->vmap = init_fontdata(data->vmap, + data->vmap_num)) == NULL) + goto err; + font_set->vmap_num = data->vmap_num; + + if(data->vrotate_type != VROTATE_NONE) { + /* A vrotate member is specified primary font data */ + /* as initial value. */ + if((font_set->vrotate = init_vrotate(data->font_data, + data->font_data_count, + data->vrotate_type, + data->vrotate, + data->vrotate_num)) == NULL) + goto err; + font_set->vrotate_num = data->font_data_count; + } + } + return True; + + err: + if(font_set->font_data) + Xfree(font_set->font_data); + if(font_set->substitute) + Xfree(font_set->substitute); + if(font_set->vmap) + Xfree(font_set->vmap); + if(font_set->vrotate) + Xfree(font_set->vrotate); + if(font_set) + Xfree(font_set); + gen->font_set = (FontSet) NULL; + gen->font_set_num = 0; + return False; + } + + /* For VW/UDC end */ + + static char * + get_prop_name(dpy, fs) + Display *dpy; + XFontStruct *fs; + { + unsigned long fp; + + if (XGetFontProperty(fs, XA_FONT, &fp)) + return XGetAtomName(dpy, fp); + + return (char *) NULL; + } + + /* For VW/UDC start */ + + static Bool + load_fontdata(oc, font_data, font_data_num) + XOC oc; + FontData font_data; + int font_data_num; + { + Display *dpy = oc->core.om->core.display; + FontData fd = font_data; + + if(font_data == NULL) return(True); + for( ; font_data_num-- ; fd++) { + if(fd->xlfd_name != (char *) NULL && fd->font == NULL) { + fd->font = XLoadQueryFont(dpy, fd->xlfd_name); + if (fd->font == NULL){ + return False; + } + } + } + return True; + } + + static Bool + load_font(oc) + XOC oc; + { + int i; + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set = gen->font_set; + int num = gen->font_set_num; + + for ( ; num-- > 0; font_set++) { + if (font_set->font_name == NULL) + continue; + + if(load_fontdata(oc, font_set->font_data, + font_set->font_data_count) != True) + return False; + + if(load_fontdata(oc, font_set->substitute, + font_set->substitute_num) != True) + return False; + + if(font_set->font_data_count > 0 && font_set->font_data->font) { + font_set->font = font_set->font_data->font; + } else if(font_set->substitute_num > 0 ) { + for(i=0;isubstitute_num;i++){ + if(font_set->substitute[i].font != NULL){ + font_set->font = font_set->substitute[i].font; + break ; + } + } + } + + /* Add 1996.05.20 */ + if( oc->core.orientation == XOMOrientation_TTB_RTL || + oc->core.orientation == XOMOrientation_TTB_LTR ){ + if (font_set->vpart_initialize == 0) { + load_fontdata(oc, font_set->vmap, font_set->vmap_num); + load_fontdata(oc, (FontData) font_set->vrotate, + font_set->vrotate_num); + font_set->vpart_initialize = 1; + } + } + + if (font_set->font->min_byte1 || font_set->font->max_byte1) + font_set->is_xchar2b = True; + else + font_set->is_xchar2b = False; + } + + return True; + } + + /* For VW/UDC end */ + + static Bool + load_font_info(oc) + XOC oc; + { + Display *dpy = oc->core.om->core.display; + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set = gen->font_set; + char **fn_list; + int fn_num, num = gen->font_set_num; + + for ( ; num-- > 0; font_set++) { + if (font_set->font_name == NULL) + continue; + + if (font_set->info == NULL) { + fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num, + &font_set->info); + if (font_set->info == NULL) + return False; + + XFreeFontNames(fn_list); + } + } + + return True; + } + + /* For Vertical Writing start */ + + static void + check_fontset_extents(overall, logical_ascent, logical_descent, font) + XCharStruct *overall; + int *logical_ascent, *logical_descent; + XFontStruct *font; + { + overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing); + overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing); + overall->ascent = max(overall->ascent, font->max_bounds.ascent); + overall->descent = max(overall->descent, font->max_bounds.descent); + overall->width = max(overall->width, font->max_bounds.width); + *logical_ascent = max(*logical_ascent, font->ascent); + *logical_descent = max(*logical_descent, font->descent); + } + + /* For Vertical Writing end */ + + static void + set_fontset_extents(oc) + XOC oc; + { + XRectangle *ink = &oc->core.font_set_extents.max_ink_extent; + XRectangle *logical = &oc->core.font_set_extents.max_logical_extent; + XFontStruct **font_list, *font; + XCharStruct overall; + int logical_ascent, logical_descent; + int num = oc->core.font_info.num_font; + + font_list = oc->core.font_info.font_struct_list; + font = *font_list++; + overall = font->max_bounds; + overall.lbearing = font->min_bounds.lbearing; + logical_ascent = font->ascent; + logical_descent = font->descent; + + /* For Vertical Writing start */ + + while (--num > 0) { + font = *font_list++; + check_fontset_extents(&overall, &logical_ascent, &logical_descent, + font); + } + + { + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set = gen->font_set; + FontData font_data; + int font_set_num = gen->font_set_num; + int font_data_count; + + for( ; font_set_num-- ; font_set++) { + if(font_set->vmap_num > 0) { + font_data = font_set->vmap; + font_data_count = font_set->vmap_num; + for( ; font_data_count-- ; font_data++) { + if(font_data->font != NULL) { + check_fontset_extents(&overall, &logical_ascent, + &logical_descent, + font_data->font); + } + } + } + + if(font_set->vrotate_num > 0) { + font_data = (FontData) font_set->vrotate; + font_data_count = font_set->vrotate_num; + for( ; font_data_count-- ; font_data++) { + if(font_data != NULL) + if(font_data->font != NULL) { + check_fontset_extents(&overall, &logical_ascent, + &logical_descent, + font_data->font); + } + } + } + } + } + + /* For Vertical Writing start */ + + ink->x = overall.lbearing; + ink->y = -(overall.ascent); + ink->width = overall.rbearing - overall.lbearing; + ink->height = overall.ascent + overall.descent; + + logical->x = 0; + logical->y = -(logical_ascent); + logical->width = overall.width; + logical->height = logical_ascent + logical_descent; + } + + static Bool + init_core_part(oc) + XOC oc; + { + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set; + int font_set_num; + XFontStruct **font_struct_list; + char **font_name_list, *font_name_buf; + int count, length; + + font_set = gen->font_set; + font_set_num = gen->font_set_num; + count = length = 0; + + for ( ; font_set_num-- > 0; font_set++) { + if (font_set->font_name == NULL) + continue; + + length += strlen(font_set->font_name) + 1; + count++; + } + if (count == 0) + return False; + + font_struct_list = (XFontStruct **) Xmalloc(sizeof(XFontStruct *) * count); + if (font_struct_list == NULL) + return False; + + font_name_list = (char **) Xmalloc(sizeof(char *) * count); + if (font_name_list == NULL) + goto err; + + font_name_buf = (char *) Xmalloc(length); + if (font_name_buf == NULL) + goto err; + + oc->core.font_info.num_font = count; + oc->core.font_info.font_name_list = font_name_list; + oc->core.font_info.font_struct_list = font_struct_list; + + font_set = gen->font_set; + font_set_num = gen->font_set_num; + + for (count = 0; font_set_num-- > 0; font_set++, count++) { + if (font_set->font_name == NULL) + continue; + + font_set->id = count; + if (font_set->font) + *font_struct_list++ = font_set->font; + else + *font_struct_list++ = font_set->info; + strcpy(font_name_buf, font_set->font_name); + Xfree(font_set->font_name); + *font_name_list++ = font_set->font_name = font_name_buf; + font_name_buf += strlen(font_name_buf) + 1; + } + + set_fontset_extents(oc); + + return True; + + err: + if (font_name_list) + Xfree(font_name_list); + Xfree(font_struct_list); + + return False; + } + + static char * + get_font_name(oc, pattern) + XOC oc; + char *pattern; + { + char **list, *name; + int count = 0; + + list = XListFonts(oc->core.om->core.display, pattern, 1, &count); + if (list == NULL) + return NULL; + + name = (char *) Xmalloc(strlen(*list) + 1); + if (name) + strcpy(name, *list); + + XFreeFontNames(list); + + return name; + } + + /* For VW/UDC start*/ + + static char + *get_rotate_fontname(font_name) + char *font_name; + { + char *pattern = NULL, *ptr = NULL; + char *fields[CHARSET_ENCODING_FIELD]; + char str_pixel[32], str_point[4]; + char rotate_font[256]; + char *rotate_font_ptr = NULL; + int pixel_size = 0; + int field_num = 0, len = 0; + + if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0) + return NULL; + + pattern = (char *)Xmalloc(len + 1); + if(!pattern) + return NULL; + strcpy(pattern, font_name); + + memset(fields, '\0', sizeof(char *) * 14); + ptr = pattern; + while(isspace(*ptr)) { + ptr++; + } + if(*ptr == '-') + ptr++; + + for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ; + ptr++, field_num++) { + fields[field_num] = ptr; + + if(ptr = strchr(ptr, '-')) { + *ptr = '\0'; + } + } + + if(field_num < CHARSET_ENCODING_FIELD) + return NULL; + + /* Pixel Size field : fields[6] */ + for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) { + if(!isdigit(*ptr)) { + if(*ptr == '['){ /* 960730 */ + strcpy(pattern, font_name); + return(pattern); + } + if(pattern) + Xfree(pattern); + return NULL; + } + } + pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]); + sprintf(str_pixel, "[ 0 ~%d %d 0 ]", pixel_size, pixel_size); + fields[6] = str_pixel; + + /* Point Size field : fields[7] */ + strcpy(str_point, "*"); + fields[POINT_SIZE_FIELD - 1] = str_point; + + rotate_font[0] = '\0'; + for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && + fields[field_num] ; field_num++) { + sprintf(rotate_font, "%s-%s", rotate_font, fields[field_num]); + } + + if(pattern) + Xfree(pattern); + + rotate_font_ptr = (char *)Xmalloc(strlen(rotate_font) + 1); + if(!rotate_font_ptr) + return NULL; + strcpy(rotate_font_ptr, rotate_font); + + return rotate_font_ptr; + } + + static Bool + is_match_charset(font_data, font_name) + FontData font_data; + char *font_name; + { + char *last; + int length, name_len; + + name_len = strlen(font_name); + last = font_name + name_len; + + length = strlen(font_data->name); + if (length > name_len) + return False; + + if (_XlcCompareISOLatin1(last - length, font_data->name) == 0) + return True; + + return False; + } + + static int + parse_all_name(oc, font_data, pattern) + XOC oc; + FontData font_data; + char *pattern; + { + + #ifdef OLDCODE + if(is_match_charset(font_data, pattern) != True) + return False; + + font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1); + if(font_data->xlfd_name == NULL) + return (-1); + + strcpy(font_data->xlfd_name, pattern); + return True; + #else /* OLDCODE */ + Display *dpy = oc->core.om->core.display; + char **fn_list = NULL, *prop_fname = NULL; + int list_num; + XFontStruct *fs_list; + + #if 0 + if(is_match_charset(font_data, pattern) != True) { + if ((fn_list = XListFontsWithInfo(dpy, pattern, + MAXFONTS, + &list_num, &fs_list)) + && (prop_fname = get_prop_name(dpy, fs_list)) + && (is_match_charset(font_data, prop_fname) != True)) { + if (fn_list) { + XFreeFontInfo(fn_list, fs_list, list_num); + fn_list = NULL; + } + return False; + } + + font_data->xlfd_name = prop_fname; + if (fn_list) { + XFreeFontInfo(fn_list, fs_list, list_num); + } + return True; + } + + font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1); + if(font_data->xlfd_name == NULL) + return (-1); + + strcpy(font_data->xlfd_name, pattern); + return True; + #else + /* + * Routine above only cares about top entry. + */ + font_data->xlfd_name = (char *)Xmalloc(strlen(pattern)+1); + if (font_data->xlfd_name == NULL) { + return (-1); + } + if (is_match_charset(font_data, pattern) != True) { + fn_list = XListFonts(dpy, pattern, 1, &list_num); + if (list_num <= 0) { + return False; + } + if (is_match_charset(font_data, fn_list[0]) != True) { + XFreeFontNames(fn_list); + return False; + } + strcpy(font_data->xlfd_name, fn_list[0]); + XFreeFontNames(fn_list); + } else { + strcpy(font_data->xlfd_name, pattern); + } + return True; + #endif + #endif /* OLDCODE */ + } + + static int + parse_omit_name(oc, font_data, pattern) + XOC oc; + FontData font_data; + char *pattern; + { + char *font_name = (char *) NULL; + char *last = (char *) NULL; + char *base_name; + char buf[BUFSIZE]; + int length = 0; + int num_fields; + + if(is_match_charset(font_data, pattern) == True) { + strcpy(buf, pattern); + length = strlen(pattern); + if (font_name = get_font_name(oc, buf)) { + font_data->xlfd_name = (char *)Xmalloc(strlen(font_name) + 1); + if(font_data->xlfd_name == NULL) { + Xfree(font_name); + return (-1); + } + strcpy(font_data->xlfd_name, font_name); + Xfree(font_name); + return True; + } + } + + strcpy(buf, pattern); + length = strlen(pattern); + last = buf + length - 1; + + /* + * Plug in the charset/encoding specified in the XLC_LOCALE file + * into the *right* place in the XLFD name. + */ + for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++) + if (*base_name == '-') num_fields++; + + switch (num_fields) { + case 12: + /* this is the best way to have specifed the fontset */ + *++last = '-'; + break; + case 13: + /* got the charset, not the encoding, zap the charset */ + last = strrchr (buf, '-'); + num_fields = 12; + break; + case 14: + /* got the charset and the encoding, zap 'em */ + last = strrchr (buf, '-'); + *last = '\0'; + last = strrchr (buf, '-'); + num_fields = 12; + break; + default: + /* punt */ + if (length > 1 && *last == '*' && *(last - 1) == '-') { + if (length > 3 && *(last - 2) == '*' && *(last - 3) == '-') + last -= 3; + else + last--; + } else { + *++last = '-'; + } + break; + } + last++; + + strcpy(last, font_data->name); + if (font_name = get_font_name(oc, buf)) { + font_data->xlfd_name = (char *)Xmalloc(strlen(font_name) + 1); + if(font_data->xlfd_name == NULL) { + Xfree(font_name); + return (-1); + } + strcpy(font_data->xlfd_name, font_name); + Xfree(font_name); + return True; + } + + while (num_fields < 12) { + *last = '*'; + *(last + 1) = '-'; + strcpy(last + 2, font_data->name); + num_fields++; + last+=2; + if (font_name = get_font_name(oc, buf)) { + font_data->xlfd_name = (char *)Xmalloc(strlen(font_name) + 1); + if(font_data->xlfd_name == NULL) { + Xfree(font_name); + return (-1); + } + strcpy(font_data->xlfd_name, font_name); + Xfree(font_name); + return True; + } + } + + return False; + } + + + typedef enum{C_PRIMARY, C_SUBSTITUTE, C_VMAP, C_VROTATE } ClassType; + + static int + parse_fontdata(oc, font_data, font_data_count, name_list, name_list_count, + class) + XOC oc; + FontData font_data; + int font_data_count; + char **name_list; + int name_list_count; + ClassType class; + { + char **cur_name_list = name_list; + char *font_name = (char *) NULL; + char *pattern = (char *) NULL; + int found_num = 0, ret = 0; + int fd_count = font_data_count; + int count = name_list_count; + Bool is_found = False; + + if(name_list == NULL || count <= 0) { + return False; + } + + if(font_data == NULL || font_data_count <= 0) { + return False; + } + + for ( ; font_data_count-- > 0; font_data++) { + is_found = False; + font_name = (char *) NULL; + count = name_list_count; + cur_name_list = name_list; + while (count-- > 0) { + pattern = *cur_name_list++; + if (pattern == NULL || *pattern == '\0') + continue; + + + /* When the font name is specified a full name. */ + if (strchr(pattern, '*') == NULL && + (font_name = get_font_name(oc, pattern))) { + + + ret = parse_all_name(oc, font_data, font_name); + Xfree(font_name); + + + if(ret == -1) + return ret; + else if (ret == True) { + found_num++; + is_found = True; + break; + } else + continue; + } + + /* When the font name is specified a omited name. */ + ret = parse_omit_name(oc, font_data, pattern); + if(ret == -1) + return ret; + else if (ret == True) { + found_num++; + is_found = True; + break; + } else + continue; + } + + switch(class) { + case C_PRIMARY: + if(is_found != True) + return False; + break; + case C_SUBSTITUTE: + case C_VMAP: + if(is_found == True) + return True; + break; + case C_VROTATE: + if(is_found == True) { + char *rotate_name; + + if((rotate_name = get_rotate_fontname(font_data->xlfd_name)) != + NULL) { + Xfree(font_data->xlfd_name); + font_data->xlfd_name = rotate_name; + return True; + } + Xfree(font_data->xlfd_name); + return False; + } + } + } + + if(class == C_PRIMARY && found_num == fd_count) + return True; + + return False; + } + + + static int + parse_vw(oc, font_set, name_list, count) + XOC oc; + FontSet font_set; + char **name_list; + int count; + { + FontData vmap = font_set->vmap; + VRotate vrotate = font_set->vrotate; + int vmap_num = font_set->vmap_num; + int vrotate_num = font_set->vrotate_num; + int ret = 0, i = 0; + + if(vmap_num > 0) { + if(parse_fontdata(oc, vmap, vmap_num, name_list, count, C_VMAP) == -1) + return (-1); + } + + if(vrotate_num > 0) { + ret = parse_fontdata(oc, (FontData) vrotate, vrotate_num, + name_list, count, C_VROTATE); + if(ret == -1) { + return (-1); + } else if(ret == False) { + CodeRange code_range; + int num_cr; + int sub_num = font_set->substitute_num; + + code_range = vrotate[i].code_range; + num_cr = vrotate[i].num_cr; + for(i = 0 ; i < vrotate_num ; i++) { + if(vrotate[i].xlfd_name) + Xfree(vrotate[i].xlfd_name); + } + Xfree(vrotate); + + if(sub_num > 0) { + vrotate = font_set->vrotate = (VRotate)Xmalloc + (sizeof(VRotateRec) * sub_num); + if(font_set->vrotate == (VRotate)NULL) + return (-1); + + for(i = 0 ; i < sub_num ; i++) { + vrotate[i].charset_name = font_set->substitute[i].name; + vrotate[i].side = font_set->substitute[i].side; + vrotate[i].code_range = code_range; + vrotate[i].num_cr = num_cr; + } + vrotate_num = font_set->vrotate_num = sub_num; + } else { + font_set->vrotate = (VRotate)NULL; + } + + ret = parse_fontdata(oc, (FontData) vrotate, vrotate_num, + name_list, count, C_VROTATE); + if(ret == -1) + return (-1); + } + } + + return True; + } + + static int + parse_fontname(oc) + XOC oc; + { + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set; + char *base_name, **name_list; + int font_set_num = 0; + int found_num = 0; + int count = 0; + int ret; + int i; + + name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count); + if (name_list == NULL) + return -1; + + font_set = gen->font_set; + font_set_num = gen->font_set_num; + + for( ; font_set_num-- > 0 ; font_set++) { + if(font_set->font_name) + continue; + + if(font_set->font_data_count > 0) { + ret = parse_fontdata(oc, font_set->font_data, + font_set->font_data_count, + name_list, count, C_PRIMARY); + if(ret == -1) { + goto err; + } else if(ret == True) { + font_set->font_name = (char *)Xmalloc + (strlen(font_set->font_data->xlfd_name) + 1); + if(font_set->font_name == (char *) NULL) + goto err; + strcpy(font_set->font_name, font_set->font_data->xlfd_name); + font_set->side = font_set->font_data->side; + + if(parse_vw(oc, font_set, name_list, count) == -1) + goto err; + found_num++; + + /* The substitute font is serched, when the primary fonts */ + /* is not found. */ + } else { + /* The primary information is free from FontSet structure */ + font_set->font_data_count = 0; + if(font_set->font_data) { + Xfree(font_set->font_data); + font_set->font_data = (FontData) NULL; + } + + /* A vrotate member is replaced to substitute information */ + /* from primary information. */ + font_set->vrotate_num = 0; + if(font_set->vrotate) { + Xfree(font_set->vrotate); + font_set->vrotate = (VRotate) NULL; + } + + ret = parse_fontdata(oc, font_set->substitute, + font_set->substitute_num, + name_list, count, C_SUBSTITUTE); + if(ret == -1) { + goto err; + } else if(ret == True) { + for(i=0;isubstitute_num;i++){ + if(font_set->substitute[i].xlfd_name != NULL){ + break; + } + } + font_set->font_name = (char *)Xmalloc + (strlen(font_set->substitute[i].xlfd_name) + 1); + if(font_set->font_name == (char *) NULL) + goto err; + strcpy(font_set->font_name,font_set->substitute[i].xlfd_name); + font_set->side = font_set->substitute[i].side; + if(parse_vw(oc, font_set, name_list, count) == -1) + goto err; + found_num++; + } + } + } else if(font_set->substitute_num > 0) { + ret = parse_fontdata(oc, font_set->substitute, + font_set->substitute_num, + name_list, count, C_SUBSTITUTE); + if(ret == -1) { + goto err; + } else if(ret == True) { + for(i=0;isubstitute_num;i++){ + if(font_set->substitute[i].xlfd_name != NULL){ + break; + } + } + font_set->font_name = (char *)Xmalloc + (strlen(font_set->substitute[i].xlfd_name) + 1); + if(font_set->font_name == (char *) NULL) + goto err; + strcpy(font_set->font_name,font_set->substitute[i].xlfd_name); + font_set->side = font_set->substitute[i].side; + if(parse_vw(oc, font_set, name_list, count) == -1) + goto err; + + found_num++; + } + } + } + + base_name = (char *) Xmalloc(strlen(oc->core.base_name_list) + 1); + if (base_name == NULL) + goto err; + + strcpy(base_name, oc->core.base_name_list); + oc->core.base_name_list = base_name; + + XFreeStringList(name_list); + + return found_num; + + err: + XFreeStringList(name_list); + + return -1; + } + + /* For VW/UDC end*/ + + static Bool + set_missing_list(oc) + XOC oc; + { + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set; + char **charset_list, *charset_buf; + int count, length, font_set_num; + int result = 1; + + font_set = gen->font_set; + font_set_num = gen->font_set_num; + count = length = 0; + + for ( ; font_set_num-- > 0; font_set++) { + if (font_set->info || font_set->font) { + continue; + } + + /* Change 1996.01.23 start */ + if(font_set->font_data_count <= 0 || + font_set->font_data == (FontData)NULL) { + if(font_set->substitute_num <= 0 || + font_set->substitute == (FontData)NULL) { + if(font_set->charset_list != NULL){ + length += + strlen(font_set->charset_list[0]->encoding_name) + 1; + } else { + length += 1; + } + } else { + length += strlen(font_set->substitute->name) + 1; + } + } else { + length += strlen(font_set->font_data->name) + 1; + } + /* Change 1996.01.23 end */ + count++; + } + + if (count < 1) { + return True; + } + + charset_list = (char **) Xmalloc(sizeof(char *) * count); + if (charset_list == NULL) { + return False; + } + + charset_buf = (char *) Xmalloc(length); + if (charset_buf == NULL) { + Xfree(charset_list); + return False; + } + + oc->core.missing_list.charset_list = charset_list; + oc->core.missing_list.charset_count = count; + + font_set = gen->font_set; + font_set_num = gen->font_set_num; + + for ( ; font_set_num-- > 0; font_set++) { + if (font_set->info || font_set->font) { + continue; + } + + /* Change 1996.01.23 start */ + if(font_set->font_data_count <= 0 || + font_set->font_data == (FontData)NULL) { + if(font_set->substitute_num <= 0 || + font_set->substitute == (FontData)NULL) { + if(font_set->charset_list != NULL){ + strcpy(charset_buf, + font_set->charset_list[0]->encoding_name); + } else { + strcpy(charset_buf, ""); + } + result = 0; + } else { + strcpy(charset_buf, font_set->substitute->name); + } + } else { + strcpy(charset_buf, font_set->font_data->name); + } + /* Change 1996.01.23 end */ + *charset_list++ = charset_buf; + charset_buf += strlen(charset_buf) + 1; + } + + if(result == 0) { + return(False); + } + + return True; + } + + static Bool + create_fontset(oc) + XOC oc; + { + XOMGenericPart *gen = XOM_GENERIC(oc->core.om); + int found_num; + + if (init_fontset(oc) == False) + return False; + + found_num = parse_fontname(oc); + if (found_num <= 0) { + if (found_num == 0) + set_missing_list(oc); + return False; + } + + if (gen->on_demand_loading == True) { + if (load_font_info(oc) == False) + return False; + } else { + if (load_font(oc) == False) + return False; + } + + if (init_core_part(oc) == False) + return False; + + if (set_missing_list(oc) == False) + return False; + + return True; + } + + /* For VW/UDC start */ + static void + free_fontdataOC(dpy,font_data, font_data_count) + Display *dpy; + FontData font_data; + int font_data_count; + { + for( ; font_data_count-- ; font_data++) { + if(font_data->xlfd_name){ + Xfree(font_data->xlfd_name); + font_data->xlfd_name = NULL; + } + if(font_data->font){ /* ADD 1996.01.7 */ + if(font_data->font->fid) /* Add 1996.01.23 */ + XFreeFont(dpy,font_data->font); /* ADD 1996.01.7 */ + else /* Add 1996.01.23 */ + XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */ + font_data->font = NULL; + } + /* XOM to kyoutuu shite shiyou sushiteiru ryouiki + kokoha free_fontdataOM() de free sareru + + if(font_data->scopes){ + Xfree(font_data->scopes); + font_data->scopes = NULL; + } + if(font_data->name){ + Xfree(font_data->name); + font_data->name = NULL; + } + */ + } + } + void destroy_fontdata(gen,dpy) + XOCGenericPart *gen ; + Display *dpy ; + { + FontSet font_set = (FontSet) NULL; + int font_set_num = 0; + + if (gen->font_set) { + font_set = gen->font_set; + font_set_num = gen->font_set_num; + for( ; font_set_num-- ; font_set++) { + if(font_set->font_data) { + free_fontdataOC(dpy, + font_set->font_data, font_set->font_data_count); + Xfree(font_set->font_data); + font_set->font_data = NULL; + } + if(font_set->substitute) { + free_fontdataOC(dpy, + font_set->substitute, font_set->substitute_num); + Xfree(font_set->substitute); + font_set->substitute = NULL; + } + if(font_set->vmap) { + free_fontdataOC(dpy, + font_set->vmap, font_set->vmap_num); + Xfree(font_set->vmap); + font_set->vmap = NULL; + } + if(font_set->vrotate) { + free_fontdataOC(dpy, + (FontData)font_set->vrotate, + font_set->vrotate_num); + Xfree(font_set->vrotate); + font_set->vrotate = NULL; + } + } + Xfree(gen->font_set); + gen->font_set = NULL; + } + } + /* For VW/UDC end */ + + static void + destroy_oc(oc) + XOC oc; + { + Display *dpy = oc->core.om->core.display; + XOCGenericPart *gen = XOC_GENERIC(oc); + XFontStruct **font_list, *font; + FontSet font_set = (FontSet) NULL; + int font_set_num = 0; + int count = 0; + + if (gen->mbs_to_cs) + _XlcCloseConverter(gen->mbs_to_cs); + + if (gen->wcs_to_cs) + _XlcCloseConverter(gen->wcs_to_cs); + + /* For VW/UDC start */ /* Change 1996.01.8 */ + destroy_fontdata(gen,dpy); + /* + */ + /* For VW/UDC end */ + + if (oc->core.base_name_list) + Xfree(oc->core.base_name_list); + + if (oc->core.font_info.font_name_list) + XFreeStringList(oc->core.font_info.font_name_list); + + if (font_list = oc->core.font_info.font_struct_list) { + Xfree(oc->core.font_info.font_struct_list); + } + + if (oc->core.missing_list.charset_list) + XFreeStringList(oc->core.missing_list.charset_list); + + #ifdef notdef + if (oc->core.res_name) + Xfree(oc->core.res_name); + if (oc->core.res_class) + Xfree(oc->core.res_class); + #endif + + Xfree(oc); + } + + static char * + set_oc_values(oc, args, num_args) + XOC oc; + XlcArgList args; + int num_args; + { + int i; + XOCGenericPart *gen = XOC_GENERIC(oc); + FontSet font_set = gen->font_set; + char *ret; + int num = gen->font_set_num; + + if (oc->core.resources == NULL) + return NULL; + + ret = _XlcSetValues((XPointer) oc, oc->core.resources, + oc->core.num_resources, args, num_args, XlcSetMask); + if(ret != NULL){ + return(ret); + } else { + for ( ; num-- > 0; font_set++) { + if (font_set->font_name == NULL) + continue; + if (font_set->vpart_initialize != 0) + continue; + if( oc->core.orientation == XOMOrientation_TTB_RTL || + oc->core.orientation == XOMOrientation_TTB_LTR ){ + load_fontdata(oc, font_set->vmap, font_set->vmap_num); + load_fontdata(oc, (FontData) font_set->vrotate, + font_set->vrotate_num); + font_set->vpart_initialize = 1; + } + } + return(NULL); + } + } + + static char * + get_oc_values(oc, args, num_args) + XOC oc; + XlcArgList args; + int num_args; + { + if (oc->core.resources == NULL) + return NULL; + + return _XlcGetValues((XPointer) oc, oc->core.resources, + oc->core.num_resources, args, num_args, XlcGetMask); + } + + static XOCMethodsRec oc_default_methods = { + destroy_oc, + set_oc_values, + get_oc_values, + _XmbDefaultTextEscapement, + _XmbDefaultTextExtents, + _XmbDefaultTextPerCharExtents, + _XmbDefaultDrawString, + _XmbDefaultDrawImageString, + _XwcDefaultTextEscapement, + _XwcDefaultTextExtents, + _XwcDefaultTextPerCharExtents, + _XwcDefaultDrawString, + _XwcDefaultDrawImageString + }; + + static XOCMethodsRec oc_generic_methods = { + destroy_oc, + set_oc_values, + get_oc_values, + _XmbGenericTextEscapement, + _XmbGenericTextExtents, + _XmbGenericTextPerCharExtents, + _XmbGenericDrawString, + _XmbGenericDrawImageString, + _XwcGenericTextEscapement, + _XwcGenericTextExtents, + _XwcGenericTextPerCharExtents, + _XwcGenericDrawString, + _XwcGenericDrawImageString + }; + + typedef struct _XOCMethodsListRec { + char *name; + XOCMethods methods; + } XOCMethodsListRec, *XOCMethodsList; + + static XOCMethodsListRec oc_methods_list[] = { + { "default", &oc_default_methods }, + { "generic", &oc_generic_methods } + }; + + static XlcResource oc_resources[] = { + { XNBaseFontName, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.base_name_list), XlcCreateMask | XlcGetMask }, + { XNOMAutomatic, NULLQUARK, sizeof(Bool), + XOffsetOf(XOCRec, core.om_automatic), XlcGetMask }, + { XNMissingCharSet, NULLQUARK, sizeof(XOMCharSetList), + XOffsetOf(XOCRec, core.missing_list), XlcGetMask }, + { XNDefaultString, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.default_string), XlcGetMask }, + { XNOrientation, NULLQUARK, sizeof(XOrientation), + XOffsetOf(XOCRec, core.orientation), XlcDefaultMask | XlcSetMask | XlcGetMask }, + { XNResourceName, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.res_name), XlcSetMask | XlcGetMask }, + { XNResourceClass, NULLQUARK, sizeof(char *), + XOffsetOf(XOCRec, core.res_class), XlcSetMask | XlcGetMask }, + { XNFontInfo, NULLQUARK, sizeof(XOMFontInfo), + XOffsetOf(XOCRec, core.font_info), XlcGetMask } + }; + + static XOC + create_oc(om, args, num_args) + XOM om; + XlcArgList args; + int num_args; + { + XOC oc; + XOMGenericPart *gen = XOM_GENERIC(om); + XOCMethodsList methods_list = oc_methods_list; + int count; + + oc = (XOC) Xmalloc(sizeof(XOCGenericRec)); + if (oc == NULL) + return (XOC) NULL; + bzero((char *) oc, sizeof(XOCGenericRec)); + + oc->core.om = om; + + if (oc_resources[0].xrm_name == NULLQUARK) + _XlcCompileResourceList(oc_resources, XlcNumber(oc_resources)); + + if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources), + args, num_args, XlcCreateMask | XlcDefaultMask)) + goto err; + + if (oc->core.base_name_list == NULL) + goto err; + + oc->core.resources = oc_resources; + oc->core.num_resources = XlcNumber(oc_resources); + + if (create_fontset(oc) == False) + goto err; + + oc->methods = &oc_generic_methods; + + if (gen->object_name) { + count = XlcNumber(oc_methods_list); + + for ( ; count-- > 0; methods_list++) { + if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) { + oc->methods = methods_list->methods; + break; + } + } + } + + return oc; + + err: + destroy_oc(oc); + + return (XOC) NULL; + } + + static void + free_fontdataOM(font_data, font_data_count) + FontData font_data; + int font_data_count; + { + for( ; font_data_count-- ; font_data++) { + if(font_data->name){ + Xfree(font_data->name); + font_data->name = NULL; + } + if(font_data->scopes){ + Xfree(font_data->scopes); + font_data->scopes = NULL; + } + } + } + + static Status + close_om(om) + XOM om; + { + XOMGenericPart *gen = XOM_GENERIC(om); + OMData data; + int count; + + if (data = gen->data) { + for (count = gen->data_num; count-- > 0; data++) { + if (data->charset_list){ + Xfree(data->charset_list); + data->charset_list = NULL; + } + /* free font_data for om */ + if (data->font_data) { + free_fontdataOM(data->font_data,data->font_data_count); + Xfree(data->font_data); + data->font_data = NULL; + } + /* free substitute for om */ + if (data->substitute) { + free_fontdataOM(data->substitute,data->substitute_num); + Xfree(data->substitute); + data->substitute = NULL; + } + /* free vmap for om */ + if (data->vmap) { + free_fontdataOM(data->vmap,data->vmap_num); + Xfree(data->vmap); + data->vmap = NULL; + } + /* free vrotate for om */ + if (data->vrotate) { + Xfree(data->vrotate); + data->vrotate = NULL; + } + } + Xfree(gen->data); + gen->data = NULL; + } + + if (gen->object_name){ + Xfree(gen->object_name); + gen->object_name = NULL; + } + + if (om->core.res_name){ + Xfree(om->core.res_name); + om->core.res_name = NULL; + } + if (om->core.res_class){ + Xfree(om->core.res_class); + om->core.res_class = NULL; + } + if (om->core.required_charset.charset_list && + om->core.required_charset.charset_count > 0){ + XFreeStringList(om->core.required_charset.charset_list); + om->core.required_charset.charset_list = NULL; + } else { + Xfree((char*)om->core.required_charset.charset_list); + om->core.required_charset.charset_list = NULL; + } + if (om->core.orientation_list.orientation){ + Xfree(om->core.orientation_list.orientation); + om->core.orientation_list.orientation = NULL; + } + + Xfree(om); + + return 1; + } + + static char * + set_om_values(om, args, num_args) + XOM om; + XlcArgList args; + int num_args; + { + if (om->core.resources == NULL) + return NULL; + + return _XlcSetValues((XPointer) om, om->core.resources, + om->core.num_resources, args, num_args, XlcSetMask); + } + + static char * + get_om_values(om, args, num_args) + XOM om; + XlcArgList args; + int num_args; + { + if (om->core.resources == NULL) + return NULL; + + return _XlcGetValues((XPointer) om, om->core.resources, + om->core.num_resources, args, num_args, XlcGetMask); + } + + static XOMMethodsRec methods = { + close_om, + set_om_values, + get_om_values, + create_oc + }; + + static XlcResource om_resources[] = { + { XNRequiredCharSet, NULLQUARK, sizeof(XOMCharSetList), + XOffsetOf(XOMRec, core.required_charset), XlcGetMask }, + { XNQueryOrientation, NULLQUARK, sizeof(XOMOrientation), + XOffsetOf(XOMRec, core.orientation_list), XlcGetMask }, + { XNDirectionalDependentDrawing, NULLQUARK, sizeof(Bool), + XOffsetOf(XOMRec, core.directional_dependent), XlcGetMask }, + { XNContextualDrawing, NULLQUARK, sizeof(Bool), + XOffsetOf(XOMRec, core.contextual_drawing), XlcGetMask } + }; + + static XOM + create_om(lcd, dpy, rdb, res_name, res_class) + XLCd lcd; + Display *dpy; + XrmDatabase rdb; + char *res_name; + char *res_class; + { + XOM om; + + om = (XOM) Xmalloc(sizeof(XOMGenericRec)); + if (om == NULL) + return (XOM) NULL; + bzero((char *) om, sizeof(XOMGenericRec)); + + om->methods = &methods; + om->core.lcd = lcd; + om->core.display = dpy; + om->core.rdb = rdb; + if (res_name) { + om->core.res_name = (char *) Xmalloc(strlen(res_name) + 1); + if (om->core.res_name == NULL) + goto err; + strcpy(om->core.res_name, res_name); + } + if (res_class) { + om->core.res_class = (char *) Xmalloc(strlen(res_class) + 1); + if (om->core.res_class == NULL) + goto err; + strcpy(om->core.res_class, res_class); + } + + if (om_resources[0].xrm_name == NULLQUARK) + _XlcCompileResourceList(om_resources, XlcNumber(om_resources)); + + om->core.resources = om_resources; + om->core.num_resources = XlcNumber(om_resources); + + return om; + + err: + close_om(om); + + return (XOM) NULL; + } + + static OMData + add_data(om) + XOM om; + { + XOMGenericPart *gen = XOM_GENERIC(om); + OMData new; + int num; + + if (num = gen->data_num) + new = (OMData) Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec)); + else + new = (OMData) Xmalloc(sizeof(OMDataRec)); + + if (new == NULL) + return NULL; + + gen->data_num = num + 1; + gen->data = new; + + new += num; + bzero((char *) new, sizeof(OMDataRec)); + + return new; + } + + /* For VW/UDC */ + + extern FontScope _XlcParse_scopemaps(); + + FontData + read_EncodingInfo(count,value) + int count; + char **value; + { + FontData font_data,ret; + char *buf, *bufptr,*scp; + FontScope scope; + int len; + font_data = (FontData) Xmalloc(sizeof(FontDataRec) * count); + if (font_data == NULL) + return NULL; + bzero((char *) font_data, sizeof(FontDataRec) * count); + + ret = font_data; + for ( ; count-- > 0; font_data++) { + /* + strcpy(buf, *value++); + */ + buf = *value; value++; + if (bufptr = strchr(buf, ':')){ + len = (int)(bufptr - buf); + bufptr++ ; + } + font_data->name = (char *) Xmalloc(len + 1); + if (font_data->name == NULL) + return NULL; + strncpy(font_data->name, buf,len); + font_data->name[len] = 0; + if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0) + font_data->side = XlcGL; + else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0) + font_data->side = XlcGR; + else + font_data->side = XlcGLGR; + + if (bufptr && (scp = strchr(bufptr, '['))){ + font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num)); + } + } + return(ret); + } + + static CodeRange read_vrotate(count,value,type,vrotate_num) + int count; + char **value; + int *type; + int *vrotate_num; + { + FontData font_data,ret; + char *buf, *bufptr,*scp; + CodeRange range; + if(!strcmp(value[0],"all")){ + *type = VROTATE_ALL ; + *vrotate_num = 0 ; + return (NULL); + } else if(*(value[0]) == '['){ + *type = VROTATE_PART ; + range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num); + return (range); + } else { + *type = VROTATE_NONE ; + *vrotate_num = 0 ; + return (NULL); + } + } + + static void read_vw(lcd,font_set,num) + XLCd lcd; + OMData font_set; + int num; + { + char **value, buf[BUFSIZ], *bufptr; + int count,i; + + sprintf(buf, "fs%d.font.vertical_map", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count > 0){ + _XlcDbg_printValue(buf,value,count); + font_set->vmap_num = count; + font_set->vmap = read_EncodingInfo(count,value); + } + + sprintf(buf, "fs%d.font.vertical_rotate", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count > 0){ + _XlcDbg_printValue(buf,value,count); + font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type), + &(font_set->vrotate_num)); + } + } + /* VW/UDC end */ + static Bool + init_om(om) + XOM om; + { + XLCd lcd = om->core.lcd; + XOMGenericPart *gen = XOM_GENERIC(om); + OMData data; + XlcCharSet *charset_list; + FontData font_data; + char **required_list; + XOrientation *orientation; + char **value, buf[BUFSIZ], *bufptr; + int count = 0, num = 0, length = 0; + + _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count); + if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0) + gen->on_demand_loading = True; + + _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count); + if (count > 0) { + gen->object_name = (char *) Xmalloc(strlen(*value) + 1); + if (gen->object_name == NULL) + return False; + strcpy(gen->object_name, *value); + } + + for (num = 0; ; num++) { + + sprintf(buf, "fs%d.charset.name", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + + if( count < 1){ + sprintf(buf, "fs%d.charset", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count < 1) + break; + } + + data = add_data(om); + if (data == NULL) + return False; + + charset_list = (XlcCharSet *) Xmalloc(sizeof(XlcCharSet) * count); + if (charset_list == NULL) + return False; + data->charset_list = charset_list; + data->charset_count = count; + + while (count-- > 0){ + *charset_list++ = _XlcGetCharSet(*value++); + } + sprintf(buf, "fs%d.charset.udc_area", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if( count > 0){ + UDCArea udc; + int i,flag = 0; + udc = (UDCArea)Xmalloc(count * sizeof(UDCAreaRec)); + if (udc == NULL) + return False; + for(i=0;icharset_count;i++){ + if(data->charset_list[i]->udc_area == NULL){ + data->charset_list[i]->udc_area = udc; + data->charset_list[i]->udc_area_num = count; + flag = 1; + } + } + if(flag == 0){ + Xfree(udc); + } + } + + sprintf(buf, "fs%d.font.primary", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count < 1){ + sprintf(buf, "fs%d.font", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count < 1) + return False; + } + + font_data = read_EncodingInfo(count,value); + if (font_data == NULL) + return False; + + data->font_data = font_data; + data->font_data_count = count; + + sprintf(buf, "fs%d.font.substitute", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count > 0){ + font_data = read_EncodingInfo(count,value); + if (font_data == NULL) + return False; + data->substitute = font_data; + data->substitute_num = count; + } else { + sprintf(buf, "fs%d.font", num); + _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count); + if (count < 1) { + data->substitute = NULL; + data->substitute_num = 0; + } else { + font_data = read_EncodingInfo(count,value); + data->substitute = font_data; + data->substitute_num = count; + } + } + read_vw(lcd,data,num); + length += strlen(data->font_data->name) + 1; + } + + /* required charset list */ + required_list = (char **) Xmalloc(sizeof(char *) * gen->data_num); + if (required_list == NULL) + return False; + + bufptr = (char *) Xmalloc(length); + if (bufptr == NULL) { + Xfree(required_list); + return False; + } + + om->core.required_charset.charset_list = required_list; + om->core.required_charset.charset_count = gen->data_num; + + count = gen->data_num; + data = gen->data; + + for ( ; count-- > 0; data++) { + strcpy(bufptr, data->font_data->name); + *required_list++ = bufptr; + bufptr += strlen(bufptr) + 1; + } + + /* orientation list */ + orientation = (XOrientation *) Xmalloc(sizeof(XOrientation) * 2); + if (orientation == NULL) + return False; + + orientation[0] = XOMOrientation_LTR_TTB; + orientation[1] = XOMOrientation_TTB_RTL; + om->core.orientation_list.orientation = orientation; + om->core.orientation_list.num_orientation = 2; + + /* directional dependent drawing */ + om->core.directional_dependent = False; + + /* contexual drawing */ + om->core.contextual_drawing = False; + + /* context dependent */ + om->core.context_dependent = False; + + return True; + } + + XOM + #if NeedFunctionPrototypes + _XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb, + _Xconst char *res_name, _Xconst char *res_class) + #else + _XomGenericOpenOM(lcd, dpy, rdb, res_name, res_class) + XLCd lcd; + Display *dpy; + XrmDatabase rdb; + char *res_name; + char *res_class; + #endif + { + XOM om; + + om = create_om(lcd, dpy, rdb, res_name, res_class); + if (om == NULL) + return (XOM) NULL; + + if (init_om(om) == False) + goto err; + + return om; + + err: + close_om(om); + + return (XOM) NULL; + } + + Bool + _XInitOM(lcd) + XLCd lcd; + { + lcd->methods->open_om = _XomGenericOpenOM; + + return True; + } + #else + static int Tk_Use_Modified_XOM = 0; + #endif /* USE_MODIFIED_XOM */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/ImakeCheck/Imakefile ./unix/ImakeCheck/Imakefile *** ../../tk8.0.5/unix/ImakeCheck/Imakefile Thu Jan 1 09:00:00 1970 --- ./unix/ImakeCheck/Imakefile Fri Jun 19 05:53:22 1998 *************** *** 0 **** --- 1,4 ---- + SRCS = dummy.c + OBJS = dummy.o + + ComplexProgramTarget(dummy) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/ImakeCheck/dummy.c ./unix/ImakeCheck/dummy.c *** ../../tk8.0.5/unix/ImakeCheck/dummy.c Thu Jan 1 09:00:00 1970 --- ./unix/ImakeCheck/dummy.c Fri Jun 19 05:53:22 1998 *************** *** 0 **** --- 1 ---- + static int noenoe; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/Makefile.in ./unix/Makefile.in *** ../../tk8.0.5/unix/Makefile.in Tue Mar 9 15:53:50 1999 --- ./unix/Makefile.in Mon May 10 19:10:27 1999 *************** *** 181,193 **** TK_CC_SEARCH_FLAGS = @TK_CC_SEARCH_FLAGS@ TK_LD_SEARCH_FLAGS = @TK_LD_SEARCH_FLAGS@ #---------------------------------------------------------------- # The information below is modified by the configure script when # Makefile is generated from Makefile.in. You shouldn't normally # modify any of this stuff by hand. #---------------------------------------------------------------- ! AC_FLAGS = @EXTRA_CFLAGS@ @DEFS@ RANLIB = @RANLIB@ SRC_DIR = @srcdir@/.. TOP_DIR = @srcdir@/.. --- 181,209 ---- TK_CC_SEARCH_FLAGS = @TK_CC_SEARCH_FLAGS@ TK_LD_SEARCH_FLAGS = @TK_LD_SEARCH_FLAGS@ + X11_IMAKE_FLAGS = @X11_IMAKE_FLAGS@ + + KANJI_OBJS = tkWFont.o tkCtext.o tkKinsoku.o tkKinput2.o tkXIM.o tkUnixFontCache.o + + KANJI_FLAGS = @KANJI_FLAGS@ + + # If you are VERY sure about your Xlib has bug-free XmbLookupString(), enable this. + #XMBLUSBUGFIXDEF = -DUSE_FIXED_XMBLOOKUPSTR + XMBLUSBUGFIXDEF = + + CACHEDIR=$(UNIX_DIR)/CacheLib + CACHEDFONTDEF = -I$(CACHEDIR) @XLIB_HACK_DEF@ + CACHEDFONTSRCS = $(CACHEDIR)/Font.c $(CACHEDIR)/FontNames.c $(CACHEDIR)/omGeneric.c \ + $(CHACHEDIR)/chkImEv.c + CACHEDFONTOBJS = Font.o FontNames.o omGeneric.o chkImEv.o + #---------------------------------------------------------------- # The information below is modified by the configure script when # Makefile is generated from Makefile.in. You shouldn't normally # modify any of this stuff by hand. #---------------------------------------------------------------- ! AC_FLAGS = @EXTRA_CFLAGS@ @DEFS@ @CPPFLAGS@ RANLIB = @RANLIB@ SRC_DIR = @srcdir@/.. TOP_DIR = @srcdir@/.. *************** *** 204,219 **** CC = @CC@ ! CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TK_SHLIB_CFLAGS} \ -I${UNIX_DIR} -I${GENERIC_DIR} \ ! -I${BMAP_DIR} -I${TCL_GENERIC_DIR} ${X11_INCLUDES} ${AC_FLAGS} ${PROTO_FLAGS} \ ! ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} ! DEPEND_SWITCHES = ${CFLAGS} -I${UNIX_DIR} -I${GENERIC_DIR} \ ! -I${BMAP_DIR} \ ! -I${TCL_GENERIC_DIR} ${X11_INCLUDES} \ ! ${AC_FLAGS} ${PROTO_FLAGS} ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} \ ! ${KEYSYM_FLAGS} WISH_OBJS = tkAppInit.o --- 220,236 ---- CC = @CC@ ! CC_SWITCHES_NORMAL = ${CFLAGS} ${CFLAGS_WARNING} \ -I${UNIX_DIR} -I${GENERIC_DIR} \ ! -I${BMAP_DIR} -I${TCL_GENERIC_DIR} \ ! ${X11_IMAKE_FLAGS} ${XMBLUSBUGFIXDEF} \ ! ${X11_INCLUDES} ${AC_FLAGS} ${PROTO_FLAGS} \ ! ${SECURITY_FLAGS} ${MEM_DEBUG_FLAGS} ${KEYSYM_FLAGS} \ ! ${KANJI_FLAGS} ${CACHEDFONTDEF} ! ! CC_SWITCHES = ${TK_SHLIB_CFLAGS} ${CC_SWITCHES_NORMAL} ! DEPEND_SWITCHES = ${CC_SWITCHES_NORMAL} WISH_OBJS = tkAppInit.o *************** *** 243,249 **** tkFocus.o tkFont.o tkGet.o tkGC.o tkGeometry.o tkGrab.o tkGrid.o \ tkMain.o tkOption.o tkPack.o tkPlace.o \ tkSelect.o tkUtil.o tkVisual.o tkWindow.o \ ! $(UNIXOBJS) $(WIDGOBJS) $(CANVOBJS) $(IMAGEOBJS) $(TEXTOBJS) SRCS = \ $(GENERIC_DIR)/tk3d.c $(GENERIC_DIR)/tkArgv.c \ --- 260,267 ---- tkFocus.o tkFont.o tkGet.o tkGC.o tkGeometry.o tkGrab.o tkGrid.o \ tkMain.o tkOption.o tkPack.o tkPlace.o \ tkSelect.o tkUtil.o tkVisual.o tkWindow.o \ ! $(UNIXOBJS) $(WIDGOBJS) $(CANVOBJS) $(IMAGEOBJS) $(TEXTOBJS) $(KANJI_OBJS) \ ! $(CACHEDFONTOBJS) SRCS = \ $(GENERIC_DIR)/tk3d.c $(GENERIC_DIR)/tkArgv.c \ *************** *** 256,261 **** --- 274,280 ---- $(GENERIC_DIR)/tkGet.c $(GENERIC_DIR)/tkGC.c \ $(GENERIC_DIR)/tkGeometry.c $(GENERIC_DIR)/tkGrab.c \ $(GENERIC_DIR)/tkGrid.c \ + $(GENERIC_DIR)/tkKinsoku.c \ $(GENERIC_DIR)/tkMain.c $(GENERIC_DIR)/tkOption.c \ $(GENERIC_DIR)/tkPack.c $(GENERIC_DIR)/tkPlace.c \ $(GENERIC_DIR)/tkSelect.c $(GENERIC_DIR)/tkUtil.c \ *************** *** 281,288 **** $(GENERIC_DIR)/tkTextIndex.c $(GENERIC_DIR)/tkTextMark.c \ $(GENERIC_DIR)/tkTextTag.c $(GENERIC_DIR)/tkTextWind.c \ $(GENERIC_DIR)/tkSquare.c $(GENERIC_DIR)/tkTest.c \ ! $(UNIX_DIR)/tkAppInit.c $(UNIX_DIR)/tkUnix.c \ ! $(UNIX_DIR)/tkUnix3d.c \ $(UNIX_DIR)/tkUnixButton.c $(UNIX_DIR)/tkUnixColor.c \ $(UNIX_DIR)/tkUnixCursor.c \ $(UNIX_DIR)/tkUnixDialog.c $(UNIX_DIR)/tkUnixDraw.c \ --- 300,308 ---- $(GENERIC_DIR)/tkTextIndex.c $(GENERIC_DIR)/tkTextMark.c \ $(GENERIC_DIR)/tkTextTag.c $(GENERIC_DIR)/tkTextWind.c \ $(GENERIC_DIR)/tkSquare.c $(GENERIC_DIR)/tkTest.c \ ! $(GENERIC_DIR)/tkWFont.c \ ! $(UNIX_DIR)/tkAppInit.c $(UNIX_DIR)/tkKinput2.c \ ! $(UNIX_DIR)/tkUnix.c $(UNIX_DIR)/tkUnix3d.c \ $(UNIX_DIR)/tkUnixButton.c $(UNIX_DIR)/tkUnixColor.c \ $(UNIX_DIR)/tkUnixCursor.c \ $(UNIX_DIR)/tkUnixDialog.c $(UNIX_DIR)/tkUnixDraw.c \ *************** *** 293,299 **** $(UNIX_DIR)/tkUnixScale.c $(UNIX_DIR)/tkUnixScrlbr.c \ $(UNIX_DIR)/tkUnixSelect.c \ $(UNIX_DIR)/tkUnixSend.c $(UNIX_DIR)/tkUnixWm.c \ ! $(UNIX_DIR)/tkUnixXId.c HDRS = bltList.h \ --- 313,319 ---- $(UNIX_DIR)/tkUnixScale.c $(UNIX_DIR)/tkUnixScrlbr.c \ $(UNIX_DIR)/tkUnixSelect.c \ $(UNIX_DIR)/tkUnixSend.c $(UNIX_DIR)/tkUnixWm.c \ ! $(UNIX_DIR)/tkUnixXId.c $(CACHEDFONTSRCS) HDRS = bltList.h \ *************** *** 322,336 **** wish: $(WISH_OBJS) $(TK_LIB_FILE) ! $(CC) @LD_FLAGS@ $(WISH_OBJS) @TK_BUILD_LIB_SPEC@ $(LIBS) \ $(TK_CC_SEARCH_FLAGS) -o wish tktest: $(TKTEST_OBJS) $(TK_LIB_FILE) ! ${CC} @LD_FLAGS@ $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ $(LIBS) \ $(TK_CC_SEARCH_FLAGS) -o tktest xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE) ! ${CC} @LD_FLAGS@ test.o tkTest.o tkSquare.o \ @TK_BUILD_LIB_SPEC@ $(LIBS) \ @TK_LD_SEARCH_FLAGS@ -lXt -o xttest --- 342,356 ---- wish: $(WISH_OBJS) $(TK_LIB_FILE) ! ${PURECOM} ${CC} @LD_FLAGS@ ${CFLAGS} $(WISH_OBJS) @TK_BUILD_LIB_SPEC@ $(LIBS) \ $(TK_CC_SEARCH_FLAGS) -o wish tktest: $(TKTEST_OBJS) $(TK_LIB_FILE) ! ${PURECOM} ${CC} @LD_FLAGS@ ${CFLAGS} $(TKTEST_OBJS) @TK_BUILD_LIB_SPEC@ $(LIBS) \ $(TK_CC_SEARCH_FLAGS) -o tktest xttest: test.o tkTest.o tkSquare.o $(TK_LIB_FILE) ! ${PURECOM} ${CC} @LD_FLAGS@ ${CFLAGS} test.o tkTest.o tkSquare.o \ @TK_BUILD_LIB_SPEC@ $(LIBS) \ @TK_LD_SEARCH_FLAGS@ -lXt -o xttest *************** *** 359,365 **** TK_LIBRARY=$(TOP_DIR)/library; export TK_LIBRARY; \ ./tktest ! install: install-binaries install-libraries install-demos install-man # Note: before running ranlib below, must cd to target directory because # some ranlibs write to current directory, and this might not always be --- 379,385 ---- TK_LIBRARY=$(TOP_DIR)/library; export TK_LIBRARY; \ ./tktest ! install: install-binaries install-libraries install-demos install-demosjp install-man # Note: before running ranlib below, must cd to target directory because # some ranlibs write to current directory, and this might not always be *************** *** 442,447 **** --- 462,494 ---- fi; \ done; + install-demosjp: + @for i in $(INSTALL_ROOT)$(prefix)/lib $(SCRIPT_INSTALL_DIR) \ + $(SCRIPT_INSTALL_DIR)/demos.jp ; \ + do \ + if [ ! -d $$i ] ; then \ + echo "Making directory $$i"; \ + mkdir $$i; \ + chmod 755 $$i; \ + else true; \ + fi; \ + done; + @for i in $(SRC_DIR)/library/demos.jp/*; \ + do \ + if [ -f $$i ] ; then \ + echo "Installing $$i"; \ + sed -e '3 s|exec wish|exec wish$(VERSION)|' \ + $$i > $(SCRIPT_INSTALL_DIR)/demos.jp/`basename $$i`; \ + fi; \ + done; + @for i in $(DEMOPROGS); \ + do \ + chmod 755 $(SCRIPT_INSTALL_DIR)/demos.jp/$$i; \ + done; + (cd $(SCRIPT_INSTALL_DIR)/demos.jp; \ + rm -rf images; \ + ln -s $(SCRIPT_INSTALL_DIR)/demos/images .) + install-man: @for i in $(MAN_INSTALL_DIR) $(MAN1_INSTALL_DIR) $(MAN3_INSTALL_DIR) $(MANN_INSTALL_DIR) ; \ do \ *************** *** 491,498 **** rm -f Makefile config.status config.cache config.log tkConfig.sh \ $(PACKAGE).* prototype depend: ! makedepend -- $(DEPEND_SWITCHES) -- $(SRCS) # Test binaries. The rule for tkTestInit.o is complicated because # it is is compiled from tkAppInit.c. Can't use the "-o" option --- 538,552 ---- rm -f Makefile config.status config.cache config.log tkConfig.sh \ $(PACKAGE).* prototype + GCCINC = -I`case "@CC@" in *gcc) echo \`@CC@ -v 2>&1 | grep specs | sed 's/specs$$/include/' | awk '{ print $$NF }'\`;; esac` + depend: ! touch .depend.tmp ! makedepend -f ./.depend.tmp -a -- $(GCCINC) $(DEPEND_SWITCHES) -- $(SRCS) ! sed -e 's:^$(GENERIC_DIR)/:./:' -e 's:^$(CACHEDIR)/:./:' ./.depend.tmp > ./.depend ! cat Makefile ./.depend > ./Makefile.tmp ! mv Makefile.tmp Makefile ! rm -f ./.depend ./.depend.tmp # Test binaries. The rule for tkTestInit.o is complicated because # it is is compiled from tkAppInit.c. Can't use the "-o" option *************** *** 503,509 **** rm -f tkAppInit.sav; \ mv tkAppInit.o tkAppInit.sav; \ fi; ! $(CC) -c $(CC_SWITCHES) -DTK_TEST $(UNIX_DIR)/tkAppInit.c rm -f tkTestInit.o mv tkAppInit.o tkTestInit.o @if test -f tkAppInit.sav ; then \ --- 557,563 ---- rm -f tkAppInit.sav; \ mv tkAppInit.o tkAppInit.sav; \ fi; ! $(CC) -c $(CC_SWITCHES_NORMAL) -DTK_TEST $(UNIX_DIR)/tkAppInit.c rm -f tkTestInit.o mv tkAppInit.o tkTestInit.o @if test -f tkAppInit.sav ; then \ *************** *** 514,520 **** $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tk3d.c tkAppInit.o: $(UNIX_DIR)/tkAppInit.c ! $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkAppInit.c tkArgv.o: $(GENERIC_DIR)/tkArgv.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkArgv.c --- 568,577 ---- $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tk3d.c tkAppInit.o: $(UNIX_DIR)/tkAppInit.c ! $(CC) -c $(CC_SWITCHES_NORMAL) $(UNIX_DIR)/tkAppInit.c ! ! tkKinput2.o: $(UNIX_DIR)/tkKinput2.c ! $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkKinput2.c tkArgv.o: $(GENERIC_DIR)/tkArgv.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkArgv.c *************** *** 540,545 **** --- 597,605 ---- tkConfig.o: $(GENERIC_DIR)/tkConfig.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkConfig.c + tkCtext.o: $(GENERIC_DIR)/tkCtext.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCtext.c + tkCursor.o: $(GENERIC_DIR)/tkCursor.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCursor.c *************** *** 570,575 **** --- 630,638 ---- tkGrid.o: $(GENERIC_DIR)/tkGrid.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkGrid.c + tkKinsoku.o: $(GENERIC_DIR)/tkKinsoku.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkKinsoku.c + tkMain.o: $(GENERIC_DIR)/tkMain.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkMain.c *************** *** 594,599 **** --- 657,665 ---- tkWindow.o: $(GENERIC_DIR)/tkWindow.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkWindow.c + tkWFont.o: $(GENERIC_DIR)/tkWFont.c + $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkWFont.c + tkButton.o: $(GENERIC_DIR)/tkButton.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkButton.c *************** *** 625,631 **** $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkScrollbar.c tkSquare.o: $(GENERIC_DIR)/tkSquare.c ! $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkSquare.c tkCanvas.o: $(GENERIC_DIR)/tkCanvas.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCanvas.c --- 691,697 ---- $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkScrollbar.c tkSquare.o: $(GENERIC_DIR)/tkSquare.c ! $(CC) -c $(CC_SWITCHES_NORMAL) $(GENERIC_DIR)/tkSquare.c tkCanvas.o: $(GENERIC_DIR)/tkCanvas.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkCanvas.c *************** *** 679,685 **** $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhoto.c tkTest.o: $(GENERIC_DIR)/tkTest.c ! $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkTest.c tkText.o: $(GENERIC_DIR)/tkText.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkText.c --- 745,751 ---- $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkImgPhoto.c tkTest.o: $(GENERIC_DIR)/tkTest.c ! $(CC) -c $(CC_SWITCHES_NORMAL) $(GENERIC_DIR)/tkTest.c tkText.o: $(GENERIC_DIR)/tkText.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tkText.c *************** *** 765,770 **** --- 831,854 ---- tkUnixXId.o: $(UNIX_DIR)/tkUnixXId.c $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixXId.c + + tkXIM.o: $(UNIX_DIR)/tkXIM.c + $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkXIM.c + + tkUnixFontCache.o: $(UNIX_DIR)/tkUnixFontCache.c + $(CC) -c $(CC_SWITCHES) $(UNIX_DIR)/tkUnixFontCache.c + + Font.o: $(CACHEDIR)/Font.c + $(CC) -c $(CC_SWITCHES) $(CACHEDIR)/Font.c + + FontNames.o: $(CACHEDIR)/FontNames.c + $(CC) -c $(CC_SWITCHES) $(CACHEDIR)/FontNames.c + + omGeneric.o: $(CACHEDIR)/omGeneric.c + $(CC) -c $(CC_SWITCHES) $(CACHEDIR)/omGeneric.c + + chkImEv.o: $(CACHEDIR)/chkImEv.c + $(CC) -c $(CC_SWITCHES) $(CACHEDIR)/chkImEv.c .c.o: $(CC) -c $(CC_SWITCHES) $< diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/configure ./unix/configure *** ../../tk8.0.5/unix/configure Tue Mar 9 15:53:50 1999 --- ./unix/configure Mon May 10 19:10:27 1999 *************** *** 1,7 **** #! /bin/sh # Guess values for system-dependent variables and create Makefiles. ! # Generated automatically using autoconf version 2.9 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation --- 1,7 ---- #! /bin/sh # Guess values for system-dependent variables and create Makefiles. ! # Generated automatically using autoconf version 2.12 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation *************** *** 18,23 **** --- 18,35 ---- ac_help="$ac_help --enable-symbols build with debugging symbols" ac_help="$ac_help + --enable-kanji enable kanji features(default)" + ac_help="$ac_help + --enable-kinput2 enable kinput2 protocol(default)" + ac_help="$ac_help + --enable-ximImprove enable better XIM protocol support(default)" + ac_help="$ac_help + --enable-xlfdCheck enable invalid XLFD name checking feature(default)" + ac_help="$ac_help + --enable-xlibHack replace some functions in Xlib for font cache" + ac_help="$ac_help + --enable-onTheSpot enable XIM on-the-spot input style support" + ac_help="$ac_help --with-x use the X Window System" ac_help="$ac_help --enable-shared build libtk as a shared library" *************** *** 59,64 **** --- 71,78 ---- # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= + # Maximum number of lines to put in a shell here document. + ac_max_here_lines=12 ac_prev= for ac_option *************** *** 340,346 **** verbose=yes ;; -version | --version | --versio | --versi | --vers) ! echo "configure generated by autoconf version 2.9" exit 0 ;; -with-* | --with-*) --- 354,360 ---- verbose=yes ;; -version | --version | --versio | --versi | --vers) ! echo "configure generated by autoconf version 2.12" exit 0 ;; -with-* | --with-*) *************** *** 442,452 **** done # NLS nuisances. ! # Only set LANG and LC_ALL to C if already set. ! # These must not be set unconditionally because not all systems understand ! # e.g. LANG=C (notably SCO). ! if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi if test "${LANG+set}" = set; then LANG=C; export LANG; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h --- 456,469 ---- done # NLS nuisances. ! # Only set these to C if already set. These must not be set unconditionally ! # because not all systems understand e.g. LANG=C (notably SCO). ! # Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! ! # Non-C LC_CTYPE values break the ctype check. if test "${LANG+set}" = set; then LANG=C; export LANG; fi + if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi + if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi + if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -rf conftest* confdefs.h *************** *** 508,513 **** --- 525,531 ---- ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' + cross_compiling=$ac_cv_prog_cc_cross if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. *************** *** 522,530 **** fi ! # RCS: @(#) $Id: configure.in,v 1.26 1999/02/04 21:00:29 stanton Exp $ ! TK_VERSION=8.0 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=0 TK_PATCH_LEVEL=".5" --- 540,548 ---- fi ! # RCS: @(#) $Id: configure,v 1.15 1999/05/08 01:05:59 m-hirano Exp $ ! TK_VERSION=8.0jp TK_MAJOR_VERSION=8 TK_MINOR_VERSION=0 TK_PATCH_LEVEL=".5" *************** *** 541,546 **** --- 559,565 ---- # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 + echo "configure:563: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 578,583 **** --- 597,603 ---- # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 + echo "configure:601: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 606,611 **** --- 626,632 ---- # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 + echo "configure:630: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 652,658 **** --- 673,719 ---- test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi + echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 + echo "configure:678: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + + ac_ext=c + # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. + ac_cpp='$CPP $CPPFLAGS' + ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' + ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' + cross_compiling=$ac_cv_prog_cc_cross + + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no + fi + rm -fr conftest* + + echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 + if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } + fi + echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 + echo "configure:712: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 + echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 + cross_compiling=$ac_cv_prog_cc_cross + echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 + echo "configure:717: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else *************** *** 661,667 **** yes; #endif EOF ! if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:665: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no --- 722,728 ---- yes; #endif EOF ! if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:726: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no *************** *** 669,697 **** fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes ! if test "${CFLAGS+set}" != set; then ! echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 ! if eval "test \"`echo '$''{'ac_cv_prog_gcc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ! ac_cv_prog_gcc_g=yes else ! ac_cv_prog_gcc_g=no fi rm -f conftest* fi ! echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6 ! if test $ac_cv_prog_gcc_g = yes; then ! CFLAGS="-g -O" ! else ! CFLAGS="-O" ! fi fi else GCC= --- 730,763 ---- fi echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + if test $ac_cv_prog_gcc = yes; then GCC=yes ! ac_test_CFLAGS="${CFLAGS+set}" ! ac_save_CFLAGS="$CFLAGS" ! CFLAGS= ! echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 ! echo "configure:741: checking whether ${CC-cc} accepts -g" >&5 ! if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo 'void f(){}' > conftest.c if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then ! ac_cv_prog_cc_g=yes else ! ac_cv_prog_cc_g=no fi rm -f conftest* fi ! echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 ! if test "$ac_test_CFLAGS" = set; then ! CFLAGS="$ac_save_CFLAGS" ! elif test $ac_cv_prog_cc_g = yes; then ! CFLAGS="-g -O2" ! else ! CFLAGS="-O2" fi else GCC= *************** *** 702,734 **** CC=${CC-cc} fi - # If we cannot run a trivial program, we must be cross compiling. - echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&6 - if eval "test \"`echo '$''{'ac_cv_c_cross'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 - else - if test "$cross_compiling" = yes; then - ac_cv_c_cross=yes - else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } - if test -s conftest && (./conftest; exit) 2>/dev/null; then - ac_cv_c_cross=no - else - ac_cv_c_cross=yes - fi - fi - rm -fr conftest* - fi - - echo "$ac_t""$ac_cv_c_cross" 1>&6 - cross_compiling=$ac_cv_c_cross echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= --- 768,776 ---- CC=${CC-cc} fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 + echo "configure:774: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= *************** *** 743,775 **** # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:753: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:768: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* CPP=/lib/cpp fi --- 785,821 ---- # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:795: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:812: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* CPP=/lib/cpp fi *************** *** 786,809 **** for ac_hdr in unistd.h limits.h do ! ac_safe=`echo "$ac_hdr" | tr './\055' '___'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:801: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi --- 832,858 ---- for ac_hdr in unistd.h limits.h do ! ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 + echo "configure:838: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:848: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi *************** *** 811,817 **** fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ! ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` cat >> confdefs.h <&6 ! ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 OLDCC="$CC" CC="$CC -pipe" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else rm -rf conftest* CC="$OLDCC" echo "$ac_t""no" 1>&6 fi rm -f conftest* - fi fi --- 889,916 ---- if test -z "$no_pipe"; then if test -n "$GCC"; then echo $ac_n "checking if the compiler understands -pipe""... $ac_c" 1>&6 + echo "configure:893: checking if the compiler understands -pipe" >&5 OLDCC="$CC" CC="$CC -pipe" cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* CC="$OLDCC" echo "$ac_t""no" 1>&6 fi rm -f conftest* fi fi *************** *** 874,880 **** withval="$with_tcl" TCL_BIN_DIR=$withval else ! TCL_BIN_DIR=`cd ../../tcl8.0$TK_PATCH_LEVEL/unix; pwd` fi if test ! -d $TCL_BIN_DIR; then --- 924,930 ---- withval="$with_tcl" TCL_BIN_DIR=$withval else ! TCL_BIN_DIR=`cd ../../tcl8.0${TK_PATCH_LEVEL}jp/unix; pwd` fi if test ! -d $TCL_BIN_DIR; then *************** *** 931,944 **** LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib" fi #-------------------------------------------------------------------- # Supply a substitute for stdlib.h if it doesn't define strtol, # strtoul, or strtod (which it doesn't in some versions of SunOS). #-------------------------------------------------------------------- echo $ac_n "checking stdlib.h""... $ac_c" 1>&6 cat > conftest.$ac_ext < EOF --- 981,1108 ---- LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib" fi + # kanji stuff. + + tclKanji="" + for i in $TCL_KANJI_DEFS + do + case $i in -DKANJI) tclKanji=yes;; esac + done + + kanji="" + KANJI_FLAGS="" + # Check whether --enable-kanji or --disable-kanji was given. + if test "${enable_kanji+set}" = set; then + enableval="$enable_kanji" + kanji=$enableval + else + kanji=yes + fi + + + if test "X$tclKanji" != "Xyes"; then + kanji=no + else + KANJI_FLAGS="$TCL_KANJI_DEFS" + fi + + if test "X$kanji" = "Xyes"; then + echo "$ac_t""kanji features are enabled." 1>&6 + + # Check whether --enable-kinput2 or --disable-kinput2 was given. + if test "${enable_kinput2+set}" = set; then + enableval="$enable_kinput2" + kinput2=$enableval + else + kinput2=yes + fi + + if test "X$kinput2" = "Xyes"; then + echo "$ac_t""kinput2 protocol is enabled." 1>&6 + KANJI_FLAGS="$KANJI_FLAGS -DKINPUT2" + else + echo "$ac_t""kinput2 protocol is disabled." 1>&6 + fi + + # Check whether --enable-ximImprove or --disable-ximImprove was given. + if test "${enable_ximImprove+set}" = set; then + enableval="$enable_ximImprove" + ximImprove=$enableval + else + ximImprove=yes + fi + + if test "X$ximImprove" = "Xyes"; then + echo "$ac_t""better XIM supporting feature is enabled." 1>&6 + KANJI_FLAGS="$KANJI_FLAGS -DXIM_IMPROVE" + else + echo "$ac_t""better XIM supporting feature is disabled." 1>&6 + fi + + # Check whether --enable-xlfdCheck or --disable-xlfdCheck was given. + if test "${enable_xlfdCheck+set}" = set; then + enableval="$enable_xlfdCheck" + xlfdCheck=$enableval + else + xlfdCheck=yes + fi + + if test "X$xlfdCheck" = "Xyes"; then + echo "$ac_t""invalid XLFD name checking feature is enabled." 1>&6 + KANJI_FLAGS="$KANJI_FLAGS -DCHECK_XLFD" + else + echo "$ac_t""invalid XLFD name checking feature is disabled." 1>&6 + fi + + # Check whether --enable-xlibHack or --disable-xlibHack was given. + if test "${enable_xlibHack+set}" = set; then + enableval="$enable_xlibHack" + xlibHack=$enableval + else + xlibHack=no + fi + + if test "X$xlibHack" = "Xyes"; then + echo "$ac_t""replace some functions in Xlib to Tk's version." 1>&6 + XLIB_HACK_DEF="-DUSE_OWN_XLQFONT -DUSE_OWN_XLSFONT -DUSE_MODIFIED_XOM" + fi + + # Check whether --enable-onTheSpot or --disable-onTheSpot was given. + if test "${enable_onTheSpot+set}" = set; then + enableval="$enable_onTheSpot" + onTheSpot=$enableval + else + onTheSpot=no + fi + + if test "X$onTheSpot" = "Xyes"; then + if test "X$ximImprove" = "Xno"; then + echo "$ac_t""you must specify --enable-ximImprove to use on-the-spot." 1>&6 + exit 1 + fi + if test "X$xlibHack" = "Xno"; then + echo "$ac_t""...Well" 1>&6 + else + echo "$ac_t""on-the-spot feature is enabled." 1>&6 + fi + XLIB_HACK_DEF="${XLIB_HACK_DEF} -DTK_USE_ON_THE_SPOT" + fi + else + echo "$ac_t""kanji features are disabled." 1>&6 + fi + + + + #-------------------------------------------------------------------- # Supply a substitute for stdlib.h if it doesn't define strtol, # strtoul, or strtod (which it doesn't in some versions of SunOS). #-------------------------------------------------------------------- echo $ac_n "checking stdlib.h""... $ac_c" 1>&6 + echo "configure:1104: checking stdlib.h" >&5 cat > conftest.$ac_ext < EOF *************** *** 953,959 **** rm -f conftest* cat > conftest.$ac_ext < EOF --- 1117,1123 ---- rm -f conftest* cat > conftest.$ac_ext < EOF *************** *** 967,973 **** rm -f conftest* cat > conftest.$ac_ext < EOF --- 1131,1137 ---- rm -f conftest* cat > conftest.$ac_ext < EOF *************** *** 999,1025 **** #-------------------------------------------------------------------- echo $ac_n "checking fd_set and sys/select""... $ac_c" 1>&6 cat > conftest.$ac_ext < ! int main() { return 0; } ! int t() { fd_set readMask, writeMask; ; return 0; } EOF ! if { (eval echo configure:1012: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* tk_ok=yes else rm -rf conftest* tk_ok=no fi rm -f conftest* - if test $tk_ok = no; then cat > conftest.$ac_ext < EOF --- 1163,1190 ---- #-------------------------------------------------------------------- echo $ac_n "checking fd_set and sys/select""... $ac_c" 1>&6 + echo "configure:1167: checking fd_set and sys/select" >&5 cat > conftest.$ac_ext < ! int main() { fd_set readMask, writeMask; ; return 0; } EOF ! if { (eval echo configure:1176: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* tk_ok=yes else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* tk_ok=no fi rm -f conftest* if test $tk_ok = no; then cat > conftest.$ac_ext < EOF *************** *** 1051,1061 **** #-------------------------------------------------------------------- echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include --- 1216,1227 ---- #-------------------------------------------------------------------- echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 + echo "configure:1220: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include *************** *** 1063,1075 **** #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1067: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 rm -rf conftest* ac_cv_header_stdc=no fi --- 1229,1243 ---- #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1233: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_stdc=no fi *************** *** 1078,1084 **** if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF --- 1246,1252 ---- if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF *************** *** 1096,1102 **** if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF --- 1264,1270 ---- if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF *************** *** 1116,1123 **** if test "$cross_compiling" = yes; then : else ! cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') --- 1284,1291 ---- if test "$cross_compiling" = yes; then : else ! cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') *************** *** 1128,1142 **** exit (0); } EOF ! { (eval echo configure:1132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } ! if test -s conftest && (./conftest; exit) 2>/dev/null; then : else ac_cv_header_stdc=no fi - fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 --- 1296,1314 ---- exit (0); } EOF ! if { (eval echo configure:1300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null ! then : else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* ac_cv_header_stdc=no fi rm -fr conftest* fi + + fi fi echo "$ac_t""$ac_cv_header_stdc" 1>&6 *************** *** 1148,1166 **** fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ! egrep "mode_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_mode_t=yes else --- 1320,1340 ---- fi echo $ac_n "checking for mode_t""... $ac_c" 1>&6 + echo "configure:1324: checking for mode_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include + #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ! egrep "mode_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_mode_t=yes else *************** *** 1179,1197 **** fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ! egrep "pid_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else --- 1353,1373 ---- fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 + echo "configure:1357: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include + #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ! egrep "pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_pid_t=yes else *************** *** 1210,1228 **** fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ! egrep "size_t" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else --- 1386,1406 ---- fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 + echo "configure:1390: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS #include + #include #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | ! egrep "size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_size_t=yes else *************** *** 1241,1251 **** fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF --- 1419,1430 ---- fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 + echo "configure:1423: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF *************** *** 1280,1303 **** for ac_hdr in sys/time.h do ! ac_safe=`echo "$ac_hdr" | tr './\055' '___'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1295: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi --- 1459,1485 ---- for ac_hdr in sys/time.h do ! ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 + echo "configure:1465: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1475: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_header_$ac_safe=no" fi *************** *** 1305,1311 **** fi if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then echo "$ac_t""yes" 1>&6 ! ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdefghijklmnopqrstuvwxyz./\055' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ___'` cat >> confdefs.h <&6 ! ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` cat >> confdefs.h <&6 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include ! int main() { return 0; } ! int t() { struct tm *tp; ; return 0; } EOF ! if { (eval echo configure:1334: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* - fi echo "$ac_t""$ac_cv_header_time" 1>&6 --- 1498,1527 ---- done echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 + echo "configure:1502: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include #include ! int main() { struct tm *tp; ; return 0; } EOF ! if { (eval echo configure:1516: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* ac_cv_header_time=no fi rm -f conftest* fi echo "$ac_t""$ac_cv_header_time" 1>&6 *************** *** 1364,1369 **** --- 1547,1553 ---- # Uses ac_ vars as temps to allow command line to override cache and checks. # --without-x overrides everything else, but does not touch the cache. echo $ac_n "checking for X""... $ac_c" 1>&6 + echo "configure:1551: checking for X" >&5 # Check whether --with-x or --without-x was given. if test "${with_x+set}" = set; then *************** *** 1403,1409 **** ac_im_usrlibdir=$ac_im_libdir; break fi done ! # Screen out bogus values from the imake configuration. case "$ac_im_incroot" in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; --- 1587,1595 ---- ac_im_usrlibdir=$ac_im_libdir; break fi done ! # Screen out bogus values from the imake configuration. They are ! # bogus both because they are the default anyway, and because ! # using them would break gcc on systems where it needs fixed includes. case "$ac_im_incroot" in /usr/include) ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes="$ac_im_incroot" ;; *************** *** 1423,1434 **** # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1432: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* --- 1609,1620 ---- # First, try using that file with no special directory specified. cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1618: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then rm -rf conftest* *************** *** 1436,1465 **** ac_x_includes= else echo "$ac_err" >&5 rm -rf conftest* # Look for the header file in a standard set of common directories. for ac_dir in \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ - /usr/X11/include \ - /usr/include/X11 \ - /usr/local/X11/include \ - /usr/local/include/X11 \ - \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ --- 1622,1653 ---- ac_x_includes= else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* # Look for the header file in a standard set of common directories. + # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in \ + /usr/X11/include \ /usr/X11R6/include \ /usr/X11R5/include \ /usr/X11R4/include \ \ + /usr/include/X11 \ /usr/include/X11R6 \ /usr/include/X11R5 \ /usr/include/X11R4 \ \ + /usr/local/X11/include \ /usr/local/X11R6/include \ /usr/local/X11R5/include \ /usr/local/X11R4/include \ \ + /usr/local/include/X11 \ /usr/local/include/X11R6 \ /usr/local/include/X11R5 \ /usr/local/include/X11R4 \ \ /usr/X386/include \ /usr/x386/include \ /usr/XFree86/include/X11 \ *************** *** 1495,1539 **** ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries= else rm -rf conftest* LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ /usr/X11R6/lib \ /usr/X11R5/lib \ /usr/X11R4/lib \ \ /usr/lib/X11R6 \ /usr/lib/X11R5 \ /usr/lib/X11R4 \ \ /usr/local/X11R6/lib \ /usr/local/X11R5/lib \ /usr/local/X11R4/lib \ \ /usr/local/lib/X11R6 \ /usr/local/lib/X11R5 \ /usr/local/lib/X11R4 \ \ - /usr/X11/lib \ - /usr/lib/X11 \ - /usr/local/X11/lib \ - /usr/local/lib/X11 \ - \ /usr/X386/lib \ /usr/x386/lib \ /usr/XFree86/lib/X11 \ --- 1683,1728 ---- ac_save_LIBS="$LIBS" LIBS="-l$x_direct_test_library $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* LIBS="$ac_save_LIBS" # We can link X programs with no special library path. ac_x_libraries= else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* LIBS="$ac_save_LIBS" # First see if replacing the include by lib works. + # Check X11 before X11Rn because it is often a symlink to the current release. for ac_dir in `echo "$ac_x_includes" | sed s/include/lib/` \ + /usr/X11/lib \ /usr/X11R6/lib \ /usr/X11R5/lib \ /usr/X11R4/lib \ \ + /usr/lib/X11 \ /usr/lib/X11R6 \ /usr/lib/X11R5 \ /usr/lib/X11R4 \ \ + /usr/local/X11/lib \ /usr/local/X11R6/lib \ /usr/local/X11R5/lib \ /usr/local/X11R4/lib \ \ + /usr/local/lib/X11 \ /usr/local/lib/X11R6 \ /usr/local/lib/X11R5 \ /usr/local/lib/X11R4 \ \ /usr/X386/lib \ /usr/x386/lib \ /usr/XFree86/lib/X11 \ *************** *** 1544,1549 **** --- 1733,1739 ---- /usr/athena/lib \ /usr/local/x11r5/lib \ /usr/lpp/Xamples/lib \ + /lib/usr/lib/X11 \ \ /usr/openwin/lib \ /usr/openwin/share/lib \ *************** *** 1558,1564 **** done fi rm -f conftest* - fi # $ac_x_libraries = NO if test "$ac_x_includes" = NO || test "$ac_x_libraries" = NO; then --- 1748,1753 ---- *************** *** 1591,1607 **** if test "$no_x" = ""; then if test "$x_includes" = ""; then cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1600: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* not_really_there="yes" fi --- 1780,1798 ---- if test "$no_x" = ""; then if test "$x_includes" = ""; then cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1789: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* not_really_there="yes" fi *************** *** 1614,1632 **** fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then echo $ac_n "checking for X11 header files""... $ac_c" 1>&6 XINCLUDES="# no special path needed" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1625: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 rm -rf conftest* XINCLUDES="nope" fi --- 1805,1826 ---- fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then echo $ac_n "checking for X11 header files""... $ac_c" 1>&6 + echo "configure:1809: checking for X11 header files" >&5 XINCLUDES="# no special path needed" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" ! { (eval echo configure:1817: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out` if test -z "$ac_err"; then : else echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* XINCLUDES="nope" fi *************** *** 1655,1660 **** --- 1849,1855 ---- if test "$no_x" = yes; then echo $ac_n "checking for X11 libraries""... $ac_c" 1>&6 + echo "configure:1853: checking for X11 libraries" >&5 XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do *************** *** 1673,1700 **** fi fi if test "$XLIBSW" = nope ; then ! echo $ac_n "checking for -lXwindow""... $ac_c" 1>&6 ! ac_lib_var=`echo Xwindow_XCreateWindow | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lXwindow $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi --- 1868,1899 ---- fi fi if test "$XLIBSW" = nope ; then ! echo $ac_n "checking for XCreateWindow in -lXwindow""... $ac_c" 1>&6 ! echo "configure:1873: checking for XCreateWindow in -lXwindow" >&5 ! ac_lib_var=`echo Xwindow'_'XCreateWindow | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lXwindow $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi *************** *** 1772,1799 **** # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- ! echo $ac_n "checking for -lXbsd""... $ac_c" 1>&6 ! ac_lib_var=`echo Xbsd_main | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lXbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi --- 1971,1998 ---- # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- ! echo $ac_n "checking for main in -lXbsd""... $ac_c" 1>&6 ! echo "configure:1976: checking for main in -lXbsd" >&5 ! ac_lib_var=`echo Xbsd'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lXbsd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi *************** *** 1811,1830 **** tk_checkBoth=0 echo $ac_n "checking for connect""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ char connect(); ! int main() { return 0; } ! int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named --- 2010,2031 ---- tk_checkBoth=0 echo $ac_n "checking for connect""... $ac_c" 1>&6 + echo "configure:2014: checking for connect" >&5 if eval "test \"`echo '$''{'ac_cv_func_connect'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char connect(); ! int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named *************** *** 1837,1852 **** ; return 0; } EOF ! if { (eval echo configure:1841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_connect=yes" else rm -rf conftest* eval "ac_cv_func_connect=no" fi rm -f conftest* - fi if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_checkSocket=0 --- 2038,2055 ---- ; return 0; } EOF ! if { (eval echo configure:2042: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_connect=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_connect=no" fi rm -f conftest* fi + if eval "test \"`echo '$ac_cv_func_'connect`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_checkSocket=0 *************** *** 1856,1883 **** fi if test "$tk_checkSocket" = 1; then ! echo $ac_n "checking for -lsocket""... $ac_c" 1>&6 ! ac_lib_var=`echo socket_main | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi --- 2059,2086 ---- fi if test "$tk_checkSocket" = 1; then ! echo $ac_n "checking for main in -lsocket""... $ac_c" 1>&6 ! echo "configure:2064: checking for main in -lsocket" >&5 ! ac_lib_var=`echo socket'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi *************** *** 1898,1917 **** tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo $ac_n "checking for accept""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ char accept(); ! int main() { return 0; } ! int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named --- 2101,2122 ---- tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" echo $ac_n "checking for accept""... $ac_c" 1>&6 + echo "configure:2105: checking for accept" >&5 if eval "test \"`echo '$''{'ac_cv_func_accept'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char accept(); ! int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named *************** *** 1924,1939 **** ; return 0; } EOF ! if { (eval echo configure:1928: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_accept=yes" else rm -rf conftest* eval "ac_cv_func_accept=no" fi rm -f conftest* - fi if eval "test \"`echo '$ac_cv_func_'accept`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_checkNsl=0 --- 2129,2146 ---- ; return 0; } EOF ! if { (eval echo configure:2133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_accept=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_accept=no" fi rm -f conftest* fi + if eval "test \"`echo '$ac_cv_func_'accept`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_checkNsl=0 *************** *** 1944,1963 **** fi echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ char gethostbyname(); ! int main() { return 0; } ! int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named --- 2151,2172 ---- fi echo $ac_n "checking for gethostbyname""... $ac_c" 1>&6 + echo "configure:2155: checking for gethostbyname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char gethostbyname(); ! int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named *************** *** 1970,2012 **** ; return 0; } EOF ! if { (eval echo configure:1974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else rm -rf conftest* eval "ac_cv_func_gethostbyname=no" fi rm -f conftest* - fi if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 ! echo $ac_n "checking for -lnsl""... $ac_c" 1>&6 ! ac_lib_var=`echo nsl_main | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi --- 2179,2223 ---- ; return 0; } EOF ! if { (eval echo configure:2183: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_gethostbyname=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_gethostbyname=no" fi rm -f conftest* fi + if eval "test \"`echo '$ac_cv_func_'gethostbyname`\" = yes"; then echo "$ac_t""yes" 1>&6 : else echo "$ac_t""no" 1>&6 ! echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6 ! echo "configure:2201: checking for main in -lnsl" >&5 ! ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi *************** *** 2037,2060 **** if test -d /usr/include/mit ; then echo $ac_n "checking MIT X libraries""... $ac_c" 1>&6 tk_oldCFlags=$CFLAGS CFLAGS="$CFLAGS -I/usr/include/mit" tk_oldLibs=$LIBS LIBS="$LIBS -lX11-mit" cat > conftest.$ac_ext < ! int main() { return 0; } ! int t() { XOpenDisplay(0); ; return 0; } EOF ! if { (eval echo configure:2058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 --- 2248,2271 ---- if test -d /usr/include/mit ; then echo $ac_n "checking MIT X libraries""... $ac_c" 1>&6 + echo "configure:2252: checking MIT X libraries" >&5 tk_oldCFlags=$CFLAGS CFLAGS="$CFLAGS -I/usr/include/mit" tk_oldLibs=$LIBS LIBS="$LIBS -lX11-mit" cat > conftest.$ac_ext < ! int main() { XOpenDisplay(0); ; return 0; } EOF ! if { (eval echo configure:2269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* echo "$ac_t""yes" 1>&6 *************** *** 2062,2077 **** XINCLUDES="-I/usr/include/mit" else rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* - CFLAGS=$tk_oldCFlags LIBS=$tk_oldLibs fi #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to --- 2273,2467 ---- XINCLUDES="-I/usr/include/mit" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* echo "$ac_t""no" 1>&6 fi rm -f conftest* CFLAGS=$tk_oldCFlags LIBS=$tk_oldLibs fi #-------------------------------------------------------------------- + # Checking X lib for i18n related things. + #-------------------------------------------------------------------- + + X11_IMAKE_FLAGS="" + tk_oldCflags=$CFLAGS + tk_oldLibs=$LIBS + CFLAGS="$CFLAGS $XINCLUDES" + LIBS="$XLIBSW $LIBS" + + echo $ac_n "checking XRegisterIMInstantiateCallback""... $ac_c" 1>&6 + echo "configure:2298: checking XRegisterIMInstantiateCallback" >&5 + cat > conftest.$ac_ext < + + int main() { + + XRegisterIMInstantiateCallback(0, 0, 0, 0, 0, 0); + + ; return 0; } + EOF + if { (eval echo configure:2311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + X11_IMAKE_FLAGS="-DHAVE_XIMREGINSTCB" + + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + + fi + rm -f conftest* + + echo $ac_n "checking XIDProc""... $ac_c" 1>&6 + echo "configure:2328: checking XIDProc" >&5 + cat > conftest.$ac_ext < + + int main() { + + XIDProc *a; + + ; return 0; } + EOF + if { (eval echo configure:2341: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + echo "$ac_t""yes" 1>&6 + + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no" 1>&6 + X11_IMAKE_FLAGS="$X11_IMAKE_FLAGS -DNO_XIDPROC" + + fi + rm -f conftest* + + HAVE_XMKMF="" + # Extract the first word of "xmkmf", so it can be a program name with args. + set dummy xmkmf; ac_word=$2 + echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 + echo "configure:2361: checking for $ac_word" >&5 + if eval "test \"`echo '$''{'ac_cv_path_HAVE_XMKMF'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + case "$HAVE_XMKMF" in + /*) + ac_cv_path_HAVE_XMKMF="$HAVE_XMKMF" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in /usr/X11R6/bin /usr/X11R5/bin /usr/local/X11R6/bin /usr/local/X11R5/bin /usr/openwin/bin /usr/X11/bin /usr/X386/bin /usr/sww/bin /usr/unsupported/bin$ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_HAVE_XMKMF="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_HAVE_XMKMF" && ac_cv_path_HAVE_XMKMF="""" + ;; + esac + fi + HAVE_XMKMF="$ac_cv_path_HAVE_XMKMF" + if test -n "$HAVE_XMKMF"; then + echo "$ac_t""$HAVE_XMKMF" 1>&6 + else + echo "$ac_t""no" 1>&6 + fi + + if test "X$HAVE_XMKMF" != "X"; then + IMAKE_FLAGS="" + (cd ./ImakeCheck; rm -f Makefile Makefile.*; eval $HAVE_XMKMF) > /dev/null 2>&1 + for i in `(cd ./ImakeCheck; make -n dummy.o)` + do + case $i in -D*) IMAKE_FLAGS="$IMAKE_FLAGS $i";; esac + done + if test "X$IMAKE_FLAGS" != "X"; then + echo "$ac_t""Add these flags for proper compile: $IMAKE_FLAGS" 1>&6 + X11_IMAKE_FLAGS="$X11_IMAKE_FLAGS $IMAKE_FLAGS" + fi + fi + + # At last check FreeBSD and have -lxpg4. + echo $ac_n "checking system version (for additional locale library)""... $ac_c" 1>&6 + echo "configure:2405: checking system version (for additional locale library)" >&5 + if test -f /usr/lib/NextStep/software_version; then + system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` + else + system=`uname -s`-`uname -r` + if test "$?" -ne 0 ; then + system=unknown + else + # Special check for weird MP-RAS system (uname returns weird + # results, and the version is kept in special file). + + if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then + system=MP-RAS-`awk '{print $3}' /etc/.relid'` + fi + if test "`uname -s`" = "AIX" ; then + system=AIX-`uname -v`.`uname -r` + fi + fi + fi + + case $system in + FreeBSD-*) + LIBS="$XLIBSW -lxpg4 $tk_oldLibs" + CFLAGS="$CFLAGS $X11_IMAKE_FLAGS" + cat > conftest.$ac_ext < + + int main() { + + (void)setlocale(LC_ALL, ""); + + ; return 0; } + EOF + if { (eval echo configure:2441: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + + echo "$ac_t""use xpg4 library." 1>&6 + XLIBSW="$XLIBSW -lxpg4" + + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + + echo "$ac_t""no need other libraries." 1>&6 + + fi + rm -f conftest* + ;; + *) + echo "$ac_t""No additional library is needed." 1>&6 + ;; + esac + + CFLAGS=$tk_oldCflags + LIBS=$tk_oldLibs + + #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to *************** *** 2080,2099 **** MATH_LIBS="" echo $ac_n "checking for sin""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ char sin(); ! int main() { return 0; } ! int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named --- 2470,2491 ---- MATH_LIBS="" echo $ac_n "checking for sin""... $ac_c" 1>&6 + echo "configure:2474: checking for sin" >&5 if eval "test \"`echo '$''{'ac_cv_func_sin'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char sin(); ! int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named *************** *** 2106,2121 **** ; return 0; } EOF ! if { (eval echo configure:2110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_sin=yes" else rm -rf conftest* eval "ac_cv_func_sin=no" fi rm -f conftest* - fi if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then echo "$ac_t""yes" 1>&6 : --- 2498,2515 ---- ; return 0; } EOF ! if { (eval echo configure:2502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_sin=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_sin=no" fi rm -f conftest* fi + if eval "test \"`echo '$ac_cv_func_'sin`\" = yes"; then echo "$ac_t""yes" 1>&6 : *************** *** 2124,2151 **** MATH_LIBS="-lm" fi ! echo $ac_n "checking for -lieee""... $ac_c" 1>&6 ! ac_lib_var=`echo ieee_main | tr '.-/+' '___p'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lieee $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi --- 2518,2545 ---- MATH_LIBS="-lm" fi ! echo $ac_n "checking for main in -lieee""... $ac_c" 1>&6 ! echo "configure:2523: checking for main in -lieee" >&5 ! ac_lib_var=`echo ieee'_'main | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lieee $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=no" fi *************** *** 2167,2186 **** #-------------------------------------------------------------------- echo $ac_n "checking for memmove""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ char memmove(); ! int main() { return 0; } ! int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named --- 2561,2582 ---- #-------------------------------------------------------------------- echo $ac_n "checking for memmove""... $ac_c" 1>&6 + echo "configure:2565: checking for memmove" >&5 if eval "test \"`echo '$''{'ac_cv_func_memmove'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char memmove(); ! int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named *************** *** 2193,2208 **** ; return 0; } EOF ! if { (eval echo configure:2197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_memmove=yes" else rm -rf conftest* eval "ac_cv_func_memmove=no" fi rm -f conftest* - fi if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then echo "$ac_t""yes" 1>&6 : --- 2589,2606 ---- ; return 0; } EOF ! if { (eval echo configure:2593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_memmove=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_memmove=no" fi rm -f conftest* fi + if eval "test \"`echo '$ac_cv_func_'memmove`\" = yes"; then echo "$ac_t""yes" 1>&6 : *************** *** 2221,2233 **** #-------------------------------------------------------------------- echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat > conftest.$ac_ext <&6 + echo "configure:2623: checking whether char is unsigned" >&5 if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$GCC" = yes; then # GCC predefines this symbol on systems where it applies. cat > conftest.$ac_ext <&2; exit 1; } else ! cat > conftest.$ac_ext <&2; exit 1; } else ! cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } ! if test -s conftest && (./conftest; exit) 2>/dev/null; then ac_cv_c_char_unsigned=yes else ac_cv_c_char_unsigned=no fi - fi rm -fr conftest* fi fi echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6 --- 2658,2676 ---- volatile char c = 255; exit(c < 0); } EOF ! if { (eval echo configure:2662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null ! then ac_cv_c_char_unsigned=yes else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* ac_cv_c_char_unsigned=no fi rm -fr conftest* fi + + fi fi echo "$ac_t""$ac_cv_c_char_unsigned" 1>&6 *************** *** 2287,2306 **** #-------------------------------------------------------------------- echo $ac_n "checking for strtod""... $ac_c" 1>&6 if eval "test \"`echo '$''{'ac_cv_func_strtod'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ char strtod(); ! int main() { return 0; } ! int t() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named --- 2690,2711 ---- #-------------------------------------------------------------------- echo $ac_n "checking for strtod""... $ac_c" 1>&6 + echo "configure:2694: checking for strtod" >&5 if eval "test \"`echo '$''{'ac_cv_func_strtod'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ + /* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ char strtod(); ! int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named *************** *** 2313,2328 **** ; return 0; } EOF ! if { (eval echo configure:2317: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then rm -rf conftest* eval "ac_cv_func_strtod=yes" else rm -rf conftest* eval "ac_cv_func_strtod=no" fi rm -f conftest* - fi if eval "test \"`echo '$ac_cv_func_'strtod`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_strtod=1 --- 2718,2735 ---- ; return 0; } EOF ! if { (eval echo configure:2722: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then rm -rf conftest* eval "ac_cv_func_strtod=yes" else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 rm -rf conftest* eval "ac_cv_func_strtod=no" fi rm -f conftest* fi + if eval "test \"`echo '$ac_cv_func_'strtod`\" = yes"; then echo "$ac_t""yes" 1>&6 tk_strtod=1 *************** *** 2333,2343 **** if test "$tk_strtod" = 1; then echo $ac_n "checking for Solaris 2.4 strtod bug""... $ac_c" 1>&6 if test "$cross_compiling" = yes; then tk_ok=0 else ! cat > conftest.$ac_ext <&6 + echo "configure:2744: checking for Solaris 2.4 strtod bug" >&5 if test "$cross_compiling" = yes; then tk_ok=0 else ! cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } ! if test -s conftest && (./conftest; exit) 2>/dev/null; then tk_ok=1 else tk_ok=0 fi - fi rm -fr conftest* if test "$tk_ok" = 1; then echo "$ac_t""ok" 1>&6 else --- 2760,2777 ---- exit(0); } EOF ! if { (eval echo configure:2764: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null ! then tk_ok=1 else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* tk_ok=0 fi rm -fr conftest* + fi + if test "$tk_ok" = 1; then echo "$ac_t""ok" 1>&6 else *************** *** 2467,2477 **** # --recheck option to rerun configure. # EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | ! sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=\${\1='\2'}/p" \ ! >> confcache if cmp -s $cache_file confcache; then : else --- 2879,2903 ---- # --recheck option to rerun configure. # EOF + # The following way of writing the cache mishandles newlines in values, + # but we know of no workaround that is simple, portable, and efficient. + # So, don't put newlines in cache variables' values. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | ! case `(ac_space=' '; set) 2>&1` in ! *ac_space=\ *) ! # `set' does not quote correctly, so add quotes (double-quote substitution ! # turns \\\\ into \\, and sed turns \\ into \). ! sed -n \ ! -e "s/'/'\\\\''/g" \ ! -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" ! ;; ! *) ! # `set' quotes correctly as required by POSIX, so do not add quotes. ! sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' ! ;; ! esac >> confcache if cmp -s $cache_file confcache; then : else *************** *** 2538,2544 **** echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) ! echo "$CONFIG_STATUS generated by autoconf version 2.9" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; --- 2964,2970 ---- echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) ! echo "$CONFIG_STATUS generated by autoconf version 2.12" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; *************** *** 2581,2586 **** --- 3007,3015 ---- s%@RANLIB@%$RANLIB%g s%@CC@%$CC%g s%@CPP@%$CPP%g + s%@KANJI_FLAGS@%$KANJI_FLAGS%g + s%@XLIB_HACK_DEF@%$XLIB_HACK_DEF%g + s%@HAVE_XMKMF@%$HAVE_XMKMF%g s%@CFLAGS_DEBUG@%$CFLAGS_DEBUG%g s%@CFLAGS_DEFAULT@%$CFLAGS_DEFAULT%g s%@CFLAGS_OPTIMIZE@%$CFLAGS_OPTIMIZE%g *************** *** 2617,2639 **** s%@XINCLUDES@%$XINCLUDES%g s%@XLIBSW@%$XLIBSW%g s%@TK_SHARED_BUILD@%$TK_SHARED_BUILD%g CEOF EOF cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then ! # Support "outfile[:infile]", defaulting infile="outfile.in". case "$ac_file" in ! *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac ! # Adjust relative srcdir, etc. for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` --- 3046,3105 ---- s%@XINCLUDES@%$XINCLUDES%g s%@XLIBSW@%$XLIBSW%g s%@TK_SHARED_BUILD@%$TK_SHARED_BUILD%g + s%@X11_IMAKE_FLAGS@%$X11_IMAKE_FLAGS%g CEOF EOF + + cat >> $CONFIG_STATUS <<\EOF + + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. + ac_file=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_cmds # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds="" + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi + EOF + cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then ! # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". case "$ac_file" in ! *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; *) ac_file_in="${ac_file}.in" ;; esac ! # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. # Remove last slash and all that follows it. Not all systems have dirname. ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` *************** *** 2657,2662 **** --- 3123,3129 ---- top_srcdir="$ac_dots$ac_given_srcdir" ;; esac + echo creating "$ac_file" rm -f "$ac_file" configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." *************** *** 2665,2679 **** # $configure_input" ;; *) ac_comsub= ;; esac sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g ! " -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file fi; done ! rm -f conftest.subs exit 0 EOF --- 3132,3152 ---- # $configure_input" ;; *) ac_comsub= ;; esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` sed -e "$ac_comsub s%@configure_input@%$configure_input%g s%@srcdir@%$srcdir%g s%@top_srcdir@%$top_srcdir%g ! " $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file fi; done ! rm -f conftest.s* + EOF + cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF exit 0 EOF diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/configure.in ./unix/configure.in *** ../../tk8.0.5/unix/configure.in Tue Mar 9 15:53:50 1999 --- ./unix/configure.in Mon May 10 19:10:28 1999 *************** *** 3,11 **** dnl generate the file "configure", which is run during Tk installation dnl to configure the system for the local environment. AC_INIT(../generic/tk.h) ! # RCS: @(#) $Id: configure.in,v 1.26 1999/02/04 21:00:29 stanton Exp $ ! TK_VERSION=8.0 TK_MAJOR_VERSION=8 TK_MINOR_VERSION=0 TK_PATCH_LEVEL=".5" --- 3,11 ---- dnl generate the file "configure", which is run during Tk installation dnl to configure the system for the local environment. AC_INIT(../generic/tk.h) ! # RCS: @(#) $Id: configure.in,v 1.14 1999/05/08 01:06:00 m-hirano Exp $ ! TK_VERSION=8.0jp TK_MAJOR_VERSION=8 TK_MINOR_VERSION=0 TK_PATCH_LEVEL=".5" *************** *** 64,70 **** #-------------------------------------------------------------------- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.0 binaries from DIR], ! TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd ../../tcl8.0$TK_PATCH_LEVEL/unix; pwd`) if test ! -d $TCL_BIN_DIR; then AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR doesn't exist) fi --- 64,70 ---- #-------------------------------------------------------------------- AC_ARG_WITH(tcl, [ --with-tcl=DIR use Tcl 8.0 binaries from DIR], ! TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd ../../tcl8.0${TK_PATCH_LEVEL}jp/unix; pwd`) if test ! -d $TCL_BIN_DIR; then AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR doesn't exist) fi *************** *** 113,118 **** --- 113,195 ---- LIB_RUNTIME_DIR="${LIB_RUNTIME_DIR}:${TCL_EXEC_PREFIX}/lib" fi + # kanji stuff. + + tclKanji="" + for i in $TCL_KANJI_DEFS + do + case $i in -DKANJI) tclKanji=yes;; esac + done + + kanji="" + KANJI_FLAGS="" + AC_ARG_ENABLE(kanji, [ --enable-kanji enable kanji features(default)], + [kanji=$enableval], [kanji=yes]) + + if test "X$tclKanji" != "Xyes"; then + kanji=no + else + KANJI_FLAGS="$TCL_KANJI_DEFS" + fi + + if test "X$kanji" = "Xyes"; then + AC_MSG_RESULT(kanji features are enabled.) + + AC_ARG_ENABLE(kinput2, [ --enable-kinput2 enable kinput2 protocol(default)], + [kinput2=$enableval], [kinput2=yes]) + if test "X$kinput2" = "Xyes"; then + AC_MSG_RESULT(kinput2 protocol is enabled.) + KANJI_FLAGS="$KANJI_FLAGS -DKINPUT2" + else + AC_MSG_RESULT(kinput2 protocol is disabled.) + fi + + AC_ARG_ENABLE(ximImprove, [ --enable-ximImprove enable better XIM protocol support(default)], + [ximImprove=$enableval], [ximImprove=yes]) + if test "X$ximImprove" = "Xyes"; then + AC_MSG_RESULT(better XIM supporting feature is enabled.) + KANJI_FLAGS="$KANJI_FLAGS -DXIM_IMPROVE" + else + AC_MSG_RESULT(better XIM supporting feature is disabled.) + fi + + AC_ARG_ENABLE(xlfdCheck, [ --enable-xlfdCheck enable invalid XLFD name checking feature(default)], + [xlfdCheck=$enableval], [xlfdCheck=yes]) + if test "X$xlfdCheck" = "Xyes"; then + AC_MSG_RESULT(invalid XLFD name checking feature is enabled.) + KANJI_FLAGS="$KANJI_FLAGS -DCHECK_XLFD" + else + AC_MSG_RESULT(invalid XLFD name checking feature is disabled.) + fi + + AC_ARG_ENABLE(xlibHack, [ --enable-xlibHack replace some functions in Xlib for font cache], + [xlibHack=$enableval], [xlibHack=no]) + if test "X$xlibHack" = "Xyes"; then + AC_MSG_RESULT(replace some functions in Xlib to Tk's version.) + XLIB_HACK_DEF="-DUSE_OWN_XLQFONT -DUSE_OWN_XLSFONT -DUSE_MODIFIED_XOM" + fi + + AC_ARG_ENABLE(onTheSpot, [ --enable-onTheSpot enable XIM on-the-spot input style support], + [onTheSpot=$enableval], [onTheSpot=no]) + if test "X$onTheSpot" = "Xyes"; then + if test "X$ximImprove" = "Xno"; then + AC_MSG_RESULT(you must specify --enable-ximImprove to use on-the-spot.) + exit 1 + fi + if test "X$xlibHack" = "Xno"; then + AC_MSG_RESULT(...Well, I think you'd better specify --enable-xlibHack to use on-the-spot.) + else + AC_MSG_RESULT(on-the-spot feature is enabled.) + fi + XLIB_HACK_DEF="${XLIB_HACK_DEF} -DTK_USE_ON_THE_SPOT" + fi + else + AC_MSG_RESULT(kanji features are disabled.) + fi + + AC_SUBST(KANJI_FLAGS) + AC_SUBST(XLIB_HACK_DEF) + #-------------------------------------------------------------------- # Supply a substitute for stdlib.h if it doesn't define strtol, # strtoul, or strtod (which it doesn't in some versions of SunOS). *************** *** 343,348 **** --- 420,518 ---- fi #-------------------------------------------------------------------- + # Checking X lib for i18n related things. + #-------------------------------------------------------------------- + + X11_IMAKE_FLAGS="" + tk_oldCflags=$CFLAGS + tk_oldLibs=$LIBS + CFLAGS="$CFLAGS $XINCLUDES" + LIBS="$XLIBSW $LIBS" + + AC_MSG_CHECKING([XRegisterIMInstantiateCallback]) + AC_TRY_LINK([ + #include + ], [ + XRegisterIMInstantiateCallback(0, 0, 0, 0, 0, 0); + ], [ + AC_MSG_RESULT(yes) + X11_IMAKE_FLAGS="-DHAVE_XIMREGINSTCB" + ], [ + AC_MSG_RESULT(no) + ]) + + AC_MSG_CHECKING([XIDProc]) + AC_TRY_COMPILE([ + #include + ], [ + XIDProc *a; + ], [ + AC_MSG_RESULT(yes) + ], [ + AC_MSG_RESULT(no) + X11_IMAKE_FLAGS="$X11_IMAKE_FLAGS -DNO_XIDPROC" + ]) + + HAVE_XMKMF="" + AC_PATH_PROG(HAVE_XMKMF, xmkmf, "", /usr/X11R6/bin /usr/X11R5/bin /usr/local/X11R6/bin /usr/local/X11R5/bin /usr/openwin/bin /usr/X11/bin /usr/X386/bin /usr/sww/bin /usr/unsupported/bin) + if test "X$HAVE_XMKMF" != "X"; then + IMAKE_FLAGS="" + (cd ./ImakeCheck; rm -f Makefile Makefile.*; eval $HAVE_XMKMF) > /dev/null 2>&1 + for i in `(cd ./ImakeCheck; make -n dummy.o)` + do + case $i in -D*) IMAKE_FLAGS="$IMAKE_FLAGS $i";; esac + done + if test "X$IMAKE_FLAGS" != "X"; then + AC_MSG_RESULT(Add these flags for proper compile: $IMAKE_FLAGS) + X11_IMAKE_FLAGS="$X11_IMAKE_FLAGS $IMAKE_FLAGS" + fi + fi + + # At last check FreeBSD and have -lxpg4. + AC_MSG_CHECKING([system version (for additional locale library)]) + if test -f /usr/lib/NextStep/software_version; then + system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version` + else + system=`uname -s`-`uname -r` + if test "$?" -ne 0 ; then + system=unknown + else + # Special check for weird MP-RAS system (uname returns weird + # results, and the version is kept in special file). + + if test -r /etc/.relid -a "X`uname -n`" = "X`uname -s`" ; then + system=MP-RAS-`awk '{print $3}' /etc/.relid'` + fi + if test "`uname -s`" = "AIX" ; then + system=AIX-`uname -v`.`uname -r` + fi + fi + fi + + case $system in + FreeBSD-*) + LIBS="$XLIBSW -lxpg4 $tk_oldLibs" + CFLAGS="$CFLAGS $X11_IMAKE_FLAGS" + AC_TRY_COMPILE([ + #include + ], [ + (void)setlocale(LC_ALL, ""); + ], [ + AC_MSG_RESULT(use xpg4 library.) + XLIBSW="$XLIBSW -lxpg4" + ], [ + AC_MSG_RESULT(no need other libraries.) + ]) + ;; + *) + AC_MSG_RESULT(No additional library is needed.) + ;; + esac + + CFLAGS=$tk_oldCflags + LIBS=$tk_oldLibs + + #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. # Also, Linux requires the "ieee" library for math to *************** *** 470,474 **** AC_SUBST(XINCLUDES) AC_SUBST(XLIBSW) AC_SUBST(TK_SHARED_BUILD) ! AC_OUTPUT(Makefile tkConfig.sh) --- 640,644 ---- AC_SUBST(XINCLUDES) AC_SUBST(XLIBSW) AC_SUBST(TK_SHARED_BUILD) ! AC_SUBST(X11_IMAKE_FLAGS) AC_OUTPUT(Makefile tkConfig.sh) Only in ../../tk8.0.5/unix: porting.old diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkConfig.sh.in ./unix/tkConfig.sh.in *** ../../tk8.0.5/unix/tkConfig.sh.in Tue Mar 9 15:53:51 1999 --- ./unix/tkConfig.sh.in Fri Mar 12 00:39:17 1999 *************** *** 20,26 **** TK_PATCH_LEVEL='@TK_PATCH_LEVEL@' # -D flags for use with the C compiler. ! TK_DEFS='@DEFS@' # Flag, 1: we built a shared lib, 0 we didn't TK_SHARED_BUILD=@TK_SHARED_BUILD@ --- 20,26 ---- TK_PATCH_LEVEL='@TK_PATCH_LEVEL@' # -D flags for use with the C compiler. ! TK_DEFS='@DEFS@ @X11_IMAKE_FLAGS@ @KANJI_FLAGS@ @XLIB_HACK_DEF@' # Flag, 1: we built a shared lib, 0 we didn't TK_SHARED_BUILD=@TK_SHARED_BUILD@ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkKinput2.c ./unix/tkKinput2.c *** ../../tk8.0.5/unix/tkKinput2.c Thu Jan 1 09:00:00 1970 --- ./unix/tkKinput2.c Tue Apr 6 20:04:16 1999 *************** *** 0 **** --- 1,1833 ---- + /* + * tkKinput2.c -- + * + * This file contains modules to implement the kanji + * input with kinput2. + * + * Copyright 1988, 1995, 1999 Software Research Associates, Inc. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + */ + + #ifndef lint + static char rcsid[] = "$Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/unix/tkKinput2.c,v 1.11 1999/04/06 10:28:48 m-hirano Exp $"; + #endif + + #if defined(KANJI) && defined(KINPUT2) + + #include "tkPort.h" + #include "tkInt.h" + + #include "tkFont.h" + + /* + * For each kinput2 server, there is a structure of the following type: + */ + + typedef struct { + int specified; + char *value; + } KI2Attr; + + typedef struct { + char *variable; + int num; + KI2Attr inputStyle; + KI2Attr focusWindow; + KI2Attr spot; + KI2Attr foreground; + KI2Attr background; + KI2Attr eventCaptureMethod; + KI2Attr lineSpacing; + KI2Attr clientArea; + KI2Attr statusArea; + KI2Attr cursor; + KI2Attr fonts; + } Kinput2Info; + + /* + * Atoms used in this module. (Japanese conversion only) + */ + + static Atom japanese_conversion_atom; + + /* + * Have atoms in this module been initialized? + */ + + static int atom_initialized = 0; + + /* + * Information about the current server. (Assuming only one server) + */ + + static Tcl_HashTable ki2infoTable; + static int ki2_initialized = 0; + + /* + * Forward declarations for procedures defined later in this file: + */ + + static void Kinput2InfoInit _ANSI_ARGS_ ((void)); + static void Kinput2InputString _ANSI_ARGS_ ((Tcl_Interp *interp, + Tk_Window tkwin, Atom selection, Atom type, + int format, unsigned long size, unsigned char *str, + ClientData clientData)); + static void Kinput2StartendProc _ANSI_ARGS_ ((Tcl_Interp *interp, + Tk_Window tkwin, Atom selection, int state, + ClientData clientData)); + static void beginConversion _ANSI_ARGS_ ((Tcl_Interp *interp, + Tk_Window tkwin, Atom catom, Atom tatom, + void (*inputproc)(), void (*startendproc)(), + ClientData clientData, Kinput2Info *ki2Ptr)); + static void endConversion _ANSI_ARGS_ ((Tcl_Interp *interp, + Tk_Window tkwin, Atom catom, int throwaway)); + static void changeConversionAttributes _ANSI_ARGS_ ((Tcl_Interp *interp, + Tk_Window tkwin, Atom catom, Kinput2Info *ki2Ptr)); + static int parseAttributes _ANSI_ARGS_ ((Tcl_Interp *interp, + int argc, char **argv, Kinput2Info *ki2Ptr)); + static char * formatAttributeInfo _ANSI_ARGS_ ((Kinput2Info *ki2Ptr, + char *attrName)); + + /* + *-------------------------------------------------------------- + * + * Tk_Kinput2Start -- + * + * This procedure is invoked to start the kanji conversion + * using kinput2. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + int + Tk_Kinput2Start(interp, tkwin, argc, argv) + Tcl_Interp *interp; /* Current interpreter. */ + Tk_Window tkwin; /* Focus window. */ + int argc; /* Number of arguments. */ + char **argv; /* Argument strings. */ + { + Tcl_HashEntry *ki2infoHashPtr; + int new; + register Kinput2Info *ki2Ptr; + char *variable = NULL; + + if (!atom_initialized) { + japanese_conversion_atom = Tk_InternAtom(tkwin, "_JAPANESE_CONVERSION"); + atom_initialized = 1; + } + if (!ki2_initialized) Kinput2InfoInit(); + + /* + * Get the Kinput2Info for the focus window. + */ + + ki2infoHashPtr = Tcl_CreateHashEntry(&ki2infoTable, (char *) tkwin, &new); + if (!new) { + ki2Ptr = (Kinput2Info *) Tcl_GetHashValue(ki2infoHashPtr); + } else { + ki2Ptr = (Kinput2Info *) ckalloc(sizeof(Kinput2Info)); + ki2Ptr->variable = NULL; + ki2Ptr->num = 0; + ki2Ptr->inputStyle.specified = None; + ki2Ptr->inputStyle.value = NULL; + ki2Ptr->focusWindow.specified = None; + ki2Ptr->focusWindow.value = NULL; + ki2Ptr->spot.specified = None; + ki2Ptr->spot.value = NULL; + ki2Ptr->foreground.specified = None; + ki2Ptr->foreground.value = NULL; + ki2Ptr->background.specified = None; + ki2Ptr->background.value = NULL; + ki2Ptr->eventCaptureMethod.specified = None; + ki2Ptr->eventCaptureMethod.value = NULL; + ki2Ptr->lineSpacing.specified = None; + ki2Ptr->lineSpacing.value = NULL; + ki2Ptr->clientArea.specified = None; + ki2Ptr->clientArea.value = NULL; + ki2Ptr->statusArea.specified = None; + ki2Ptr->statusArea.value = NULL; + ki2Ptr->cursor.specified = None; + ki2Ptr->cursor.value = NULL; + ki2Ptr->fonts.specified = None; + ki2Ptr->fonts.value = NULL; + + Tcl_SetHashValue(ki2infoHashPtr, ki2Ptr); + } + + /* + * Parse the arguments and update the Kinput2Info. + */ + + if (parseAttributes(interp, argc, argv, ki2Ptr) == TCL_ERROR) { + return TCL_ERROR; + } + + if (ki2Ptr->variable) { + variable = (char *) ckalloc((unsigned)(strlen(ki2Ptr->variable) + 1)); + strcpy(variable, ki2Ptr->variable); + } + + beginConversion(interp, tkwin, japanese_conversion_atom, Tk_UsefulAtom(tkwin, compoundTextAtom), + Kinput2InputString, Kinput2StartendProc, (ClientData) variable, ki2Ptr); + + return (strlen(interp->result) == 0) ? TCL_OK : TCL_ERROR; + } + + /* + *-------------------------------------------------------------- + * + * Tk_Kinput2End -- + * + * This procedure is invoked to end the kanji conversion + * using kinput2. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + int + Tk_Kinput2End(interp, tkwin) + Tcl_Interp *interp; /* Current interpreter. */ + Tk_Window tkwin; /* Focus window.*/ + { + if (!atom_initialized) { + Tcl_SetResult(interp, "kanjiInput is never started.", TCL_VOLATILE); + return TCL_ERROR; + } + + endConversion(interp, tkwin, japanese_conversion_atom, True); + + return (strlen(interp->result) == 0) ? TCL_OK : TCL_ERROR; + } + + /* + *-------------------------------------------------------------- + * + * Tk_Kinput2Attribute -- + * + * This procedure is invoked to change the attributes for + * the kanji conversion using kinput2. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + int + Tk_Kinput2Attribute(interp, tkwin, argc, argv) + Tcl_Interp *interp; /* Current interpreter. */ + Tk_Window tkwin; /* Focus window. */ + int argc; /* Number of arguments. */ + char **argv; /* Argument strings. */ + { + Tcl_HashEntry *ki2infoHashPtr; + register Kinput2Info *ki2Ptr; + int saved1, saved2; + + if (!ki2_initialized) { + Tcl_SetResult(interp, "kanjiInput is never started.", TCL_VOLATILE); + return TCL_ERROR; + } + + ki2infoHashPtr = Tcl_FindHashEntry(&ki2infoTable, (char *) tkwin); + if (ki2infoHashPtr == NULL) { + Tcl_SetResult(interp, + "No hash entry: kanjiInput 'attribute' is invoked before 'start'", + TCL_VOLATILE); + return TCL_ERROR; + } + ki2Ptr = (Kinput2Info *) Tcl_GetHashValue(ki2infoHashPtr); + + /* + * Parse the arguments and update the Kinput2Info. + */ + + if (parseAttributes(interp, argc, argv, ki2Ptr) == TCL_ERROR) { + return TCL_ERROR; + } + saved1 = ki2Ptr->inputStyle.specified; + saved2 = ki2Ptr->eventCaptureMethod.specified; + ki2Ptr->inputStyle.specified = None; + ki2Ptr->eventCaptureMethod.specified = None; + + changeConversionAttributes(interp, tkwin, japanese_conversion_atom, ki2Ptr); + + ki2Ptr->inputStyle.specified = saved1; + ki2Ptr->eventCaptureMethod.specified = saved2; + + return (strlen(interp->result) == 0) ? TCL_OK : TCL_ERROR; + } + + /* + *-------------------------------------------------------------- + * + * Tk_Kinput2AttributeInfo -- + * + * This procedure is invoked to show the attributes for + * the kanji conversion using kinput2. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + int + Tk_Kinput2AttributeInfo(interp, tkwin, attrName) + Tcl_Interp *interp; /* Current interpreter. */ + Tk_Window tkwin; /* Window to focus. */ + char *attrName; /* If non-NULL, indicates a single option + * whose info is to be returned. Otherwise + * info is returned for all options. */ + { + Tcl_HashEntry *ki2infoHashPtr; + register Kinput2Info *ki2Ptr; + char *list; + + if (!ki2_initialized) { + Tcl_SetResult(interp, "kanjiInput is never started.", TCL_VOLATILE); + return TCL_ERROR; + } + + ki2infoHashPtr = Tcl_FindHashEntry(&ki2infoTable, (char *) tkwin); + if (ki2infoHashPtr == NULL) { + Tcl_SetResult(interp, + "No hash entry: kanjiInput 'attribute' is invoked before 'start'", + TCL_VOLATILE); + return TCL_ERROR; + } + ki2Ptr = (Kinput2Info *) Tcl_GetHashValue(ki2infoHashPtr); + + /* + * Create a valid Tcl list holding the attributes of the kinput2. + */ + + Tcl_SetResult(interp, (char *) NULL, TCL_STATIC); + + if (attrName != NULL) { + list = formatAttributeInfo(ki2Ptr, attrName); + if (list == NULL) { + Tcl_AppendResult(interp, "unknown attribute \"", attrName, "\"", + (char *) NULL); + return TCL_ERROR; + } + interp->result = list; + interp->freeProc = TCL_DYNAMIC; + } else { + list = formatAttributeInfo(ki2Ptr, "-variable"); + Tcl_AppendResult(interp, "{", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-inputStyle"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-focusWindow"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-spot"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-foreground"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-background"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-eventCaptureMethod"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-lineSpacing"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-clientArea"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-statusArea"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-cursor"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + list = formatAttributeInfo(ki2Ptr, "-fonts"); + Tcl_AppendResult(interp, " {", list, "}", (char *) NULL); + ckfree(list); + } + + return TCL_OK; + } + + /* + *---------------------------------------------------------------------- + * + * Kinput2InfoInit -- + * + * Initialize the structures used for Kinput2Info management. + * + * Results: + * None. + * + * Side effects: + * Read the code. + * + *---------------------------------------------------------------------- + */ + + static void + Kinput2InfoInit() + { + ki2_initialized = 1; + Tcl_InitHashTable(&ki2infoTable, TCL_ONE_WORD_KEYS); + } + + /* + *-------------------------------------------------------------- + * + * Kinput2InputString -- + * + * This procedure is invoked when the application receives + * the kanji string from kinput2 server. + * + * Results: + * None. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + static void + Kinput2InputString(interp, tkwin, selection, type, format, size, str, clientData) + Tcl_Interp *interp; + Tk_Window tkwin; + Atom selection; + Atom type; + int format; + unsigned long size; + unsigned char *str; + ClientData clientData; + { + if (str == NULL) { + return; + } else { + int kanjiCode = Tcl_KanjiCode(interp); + char *variable = (char *) clientData; + int len; + wchar *wstr; + char *kanjiStr; + + if (variable == NULL) return; + + wstr = Tk_CtextToWStr(str, (int)size); + if (wstr == NULL) return; + + len = Tcl_KanjiDecode(kanjiCode, wstr, NULL); + kanjiStr = (char *) ckalloc((unsigned)(len + 1)); + (void) Tcl_KanjiDecode(kanjiCode, wstr, kanjiStr); + + Tcl_SetVar(interp, variable, kanjiStr, TCL_GLOBAL_ONLY); + + ckfree((char *)wstr); + ckfree(kanjiStr); + } + } + + /* + *-------------------------------------------------------------- + * + * Kinput2StartendProc -- + * + * This procedure is invoked when a conversion starts, ends, + * or aborts. + * + * Results: + * None. + * + * Side effects: + * See the user documentation. + * + *-------------------------------------------------------------- + */ + + static void + Kinput2StartendProc(interp, tkwin, selection, state, clientData) + Tcl_Interp *interp; + Tk_Window tkwin; + Atom selection; + int state; + ClientData clientData; + { + switch (state) { + case 0: /* start */ + break; + case 1: /* end */ + /* fall through */ + default: /* error */ + /* free memory for the variable name */ + if (clientData != NULL) ckfree((char *)clientData); + } + } + + /* + * Procedures for kanji conversion with kinput2. + */ + + #include "tkKinput2.h" + + typedef struct { + Display *display; + Atom profileAtom; /* "_CONVERSION_PROFILE" */ + Atom typeAtom; /* "_CONVERSION_ATTRIBUTE_TYPE" */ + Atom versionAtom; /* "PROTOCOL-2.0" */ + Atom reqAtom; /* "CONVERSION_REQUEST" */ + Atom notifyAtom; /* "CONVERSION_NOTIFY" */ + Atom endAtom; /* "CONVERSION_END" */ + Atom endReqAtom; /* "CONVERSION_END_REQUEST" */ + Atom attrAtom; /* "CONVERSION_ATTRIBUTE" */ + Atom attrNotifyAtom; /* "CONVERSION_ATTRIBUTE_NOTIFY" */ + } ConversionAtoms; + + typedef struct { + Tcl_Interp *interp; + Tk_Window tkwin; + Atom convatom; + Window convowner; + Window forwardwin; + Atom property; + void (*inputproc)(); + void (*startendproc)(); + ClientData clientData; + } ConversionContext; + + static XContext convertPrivContext; + + /* + * Forward declarations for procedures defined later in this file: + */ + + static void finishConversion _ANSI_ARGS_ ((Tk_Window tkwin, + ConversionContext *context)); + static int recvConvAck _ANSI_ARGS_((ClientData clientData, + XEvent *eventPtr)); + static int getConv _ANSI_ARGS_((ClientData clientData, + XEvent *eventPtr)); + static void callStart _ANSI_ARGS_((Tk_Window tkwin, + ConversionContext *context)); + static void callFail _ANSI_ARGS_((Tk_Window tkwin, + ConversionContext *context)); + static void callEnd _ANSI_ARGS_((Tk_Window tkwin, + ConversionContext *context)); + static ConversionAtoms *getAtoms _ANSI_ARGS_ ((Tk_Window tkwin)); + static ConversionContext *getConversionContext _ANSI_ARGS_ ((Tk_Window tkwin)); + static int makeAttrData _ANSI_ARGS_ ((Tcl_Interp *interp, + Tk_Window tkwin, Kinput2Info *ki2Ptr, + unsigned long **datap)); + static void forwardKeyEvent _ANSI_ARGS_ ((ClientData clientdata, + XEvent *event)); + static int stopForwarding _ANSI_ARGS_ ((ClientData clientdata, + XErrorEvent *errEvent)); + + /* + *-------------------------------------------------------------- + * + * beginConversion -- + * + * Find a kanji conversion server and invoke it. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static void + beginConversion(interp, tkwin, catom, tatom, inputproc, startendproc, clientData, ki2Ptr) + Tcl_Interp *interp; + Tk_Window tkwin; + Atom catom; /* Selection Atom e.g. JAPANESE_CONVERSION */ + Atom tatom; /* Property Type Atom e.g. COMPOUND_TEXT */ + void (*inputproc)(); /* conversion text callback function */ + void (*startendproc)(); /* conversion start/end callback function */ + ClientData clientData; /* client_data passed to callback function */ + Kinput2Info *ki2Ptr; + { + Window owner; + XEvent event; + ConversionAtoms *cap; + ConversionContext *context; + int anyattr = False; + static int checkProtocols _ANSI_ARGS_ ((Display *dpy, + Window window, ConversionAtoms *cap)); + + cap = getAtoms(tkwin); + + /* ハムエケ・オ。シ・ミ、テオ、ケ */ + if ((owner = XGetSelectionOwner(Tk_Display(tkwin), catom)) == None) { + /* 、ハ、、 + * 、筅キ、簗ムエケテ讀タ、テ、ソ、鯡ムエケ、テ貊゚、ケ、 + */ + Tcl_SetResult(interp, "Conversion Server not found", TCL_VOLATILE); + if ((context = getConversionContext(tkwin)) != NULL) { + callEnd(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + } + return; + } + + /* + * コ」、ケ、ヌ、ヒハムエケテ讀ォ、ノ、ヲ、ォトエ、ル、 + * ハムエケテ讀ハ、魎ソ、筅サ、コ、ヒ・・ソ。シ・、ケ、。ト、、ア、ヒ、マ、、、ォ、ハ、、 + * 、ハ、シ、ォ、ネ、、、ヲ、ネ。「ハムエケ・オ。シ・ミ、ャイソ、鬢ォ、ホサセ、ヌナモテ讀ヌサ爨、タセケ + * CONVERSION_END 、ャ・ッ・鬣、・「・・ネ、ヒヘ隍ハ、、、ウ、ネ、ャ、「、、ォ、鬢ヌ、「、 + * 、ス、ウ、ヌ。「ハムエケテ讀ホセケ遉ヌ、 SelectionOwner 、テオ、キ、ニ。「、ス、、ャ + * コヌス鬢ヒ _beginConversion() 、ャクニ、ミ、、ソサ、ネ WindowID 、ャニア、ク、ォ + * 、ノ、ヲ、ォウホヌァ、ケ、 + * ヒワナ、マ SelectionOwner 、ヒ、ハ、テ、ソサエヨ、筵チ・ァ・テ・ッ、キ、ソ、、、ホ、タ、ャ + * ICCCM 、ヒスメ、ル、鬢、ニ、、、、隍ヲ、ヒ。「GetSelectionOwner 、ヌ、マ + * 、ス、、ャ、、ォ、鬢ハ、、、ホ、ヌ、「、ュ、鬢皃 + */ + if ((context = getConversionContext(tkwin)) != NULL) { + Window curOwner; + curOwner = (catom == context->convatom) ? owner : + XGetSelectionOwner(Tk_Display(tkwin), context->convatom); + if (curOwner == context->convowner) { + /* イソ、筅サ、コ、ヒ・・ソ。シ・ */ + return; + } + /* SelectionOwner 、ャハム、、テ、ニ、、、 + * 、ウ、、マナモテ讀ヌハムエケ・オ。シ・ミ、ャ・ッ・鬣テ・キ・螟キ、ソ、ヒー网、、ハ、、 + * 、ネ、、、ヲ、ウ、ネ、ヌ CONVERSION_END 、ャヘ隍ソサ、ネニア、ク、隍ヲ、ハ + * ス靉、、ケ、 + */ + callEnd(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + } + + /* + * ・オ。シ・ミ、ォ、鬢ホ CONVERSION_NOTIFY ヘム、ホ・、・ル・・ネ・マ・・ノ・鬢 + * ナミマソ、ケ、 + */ + Tk_CreateGenericHandler((Tk_GenericProc *)recvConvAck, (ClientData)tkwin); + + /* + * ・ウ・・ニ・ュ・ケ・ネ、、ト、ッ、テ、ニノャヘラ、ハセハ、ナミマソ、ケ、 + */ + context = (ConversionContext *) ckalloc((unsigned)sizeof(ConversionContext)); + context->interp = interp; + context->tkwin = tkwin; + context->convatom = catom; + context->convowner = owner; + context->forwardwin = None; + context->property = None; /* 、ウ、、マ CONVERSION_NOTIFY 、ャヘ隍ソサ、ヒ + * タオ、キ、ッタ゚ト熙オ、、 */ + context->inputproc = inputproc; + context->startendproc = startendproc; + context->clientData = clientData; + XSaveContext(Tk_Display(tkwin), Tk_WindowId(tkwin), + convertPrivContext, (caddr_t)context); + + /* + * ハムエケツータュ・・ケ・ネ、ャサリト熙オ、、ニ、、、、ミ・ラ・・ム・ニ・」、ヒ、ス、、ナミマソ、ケ、 + */ + if (ki2Ptr->num > 0 && checkProtocols(Tk_Display(tkwin), owner, cap)) { + unsigned long *data; + int len; + + if ((len = makeAttrData(interp, tkwin, ki2Ptr, &data)) > 0) { + XChangeProperty(Tk_Display(tkwin), Tk_WindowId(tkwin), + cap->attrAtom, cap->attrAtom, 32, + PropModeReplace, (unsigned char *) data, len); + ckfree((char *) data); + anyattr = True; + } + } + + /* + * ClientMessage ・、・ル・・ネ、サネ、テ、ニニヒワクニホマ、・・ッ・ィ・ケ・ネ、ケ、 + */ + event.xclient.type = ClientMessage; + event.xclient.window = owner; + event.xclient.message_type = cap->reqAtom; + event.xclient.format = 32; + event.xclient.data.l[0] = catom; + event.xclient.data.l[1] = Tk_WindowId(tkwin); + event.xclient.data.l[2] = tatom; + /* キイフ、・ケ・ネ・「、ケ、・ラ・・ム・ニ・」フセ、マ。「ツソクタク、ニアサ、ヒサネヘム、ケ、、ウ、ネ、 + * ケヘ、ィ、ニ。「selection atom 、サネヘム、ケ、、ウ、ネ、ヒ、ケ、 + */ + event.xclient.data.l[3] = catom; + event.xclient.data.l[4] = anyattr ? cap->attrAtom : None; + XSendEvent(Tk_Display(tkwin), owner, False, NoEventMask, &event); + } + + /* + *-------------------------------------------------------------- + * + * endConversion -- + * + * Terminate kanji conversion. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static void + endConversion(interp, tkwin, catom, throwaway) + Tcl_Interp *interp; + Tk_Window tkwin; + Atom catom; /* Selection Atom */ + int throwaway; + { + XEvent event; + ConversionAtoms *cap; + ConversionContext *context; + + cap = getAtoms(tkwin); + context = getConversionContext(tkwin); + + if (context == NULL || (catom != None && catom != context->convatom)) { + return; + } + + if (XGetSelectionOwner(Tk_Display(tkwin), context->convatom) != + context->convowner) { + /* ・ウ。シ・・ミ・テ・ッ、クニ、ヨ */ + callEnd(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + return; + } + + if (throwaway) context->inputproc = NULL; + + event.xclient.type = ClientMessage; + event.xclient.window = context->convowner; + event.xclient.message_type = cap->endReqAtom; + event.xclient.format = 32; + event.xclient.data.l[0] = context->convatom; + event.xclient.data.l[1] = Tk_WindowId(tkwin); + + XSendEvent(Tk_Display(tkwin), context->convowner, False, NoEventMask, &event); + } + + /* + *-------------------------------------------------------------- + * + * changeConversionAttributes -- + * + * Change attributes of a conversion server. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static void + changeConversionAttributes(interp, tkwin, catom, ki2Ptr) + Tcl_Interp *interp; + Tk_Window tkwin; + Atom catom; + Kinput2Info *ki2Ptr; + { + XEvent event; + ConversionAtoms *cap; + ConversionContext *context; + unsigned long *data; + int len; + + if (ki2Ptr->num == 0) return; + + cap = getAtoms(tkwin); + context = getConversionContext(tkwin); + + if (context == NULL || (catom != None && catom != context->convatom)) { + return; + } + + if (XGetSelectionOwner(Tk_Display(tkwin), context->convatom) != + context->convowner) { + callEnd(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + return; + } + + data = NULL; + if ((len = makeAttrData(interp, tkwin, ki2Ptr, &data)) == 0) return; + + event.xclient.type = ClientMessage; + event.xclient.window = context->convowner; + event.xclient.message_type = cap->attrNotifyAtom; + event.xclient.format = 32; + event.xclient.data.l[0] = context->convatom; + event.xclient.data.l[1] = Tk_WindowId(tkwin); + if (len <= 3 && len == LENGTH_OF_ATTR(data[0]) + 1) { + int i; + /* ・、・ル・・ネ、ホテ讀ヒシ、゙、 */ + for (i = 0; i < len; i++) { + event.xclient.data.l[2 + i] = data[i]; + } + } else { + XChangeProperty(Tk_Display(tkwin), Tk_WindowId(tkwin), + cap->attrAtom, cap->attrAtom, 32, + PropModeReplace, (unsigned char *)data, len); + event.xclient.data.l[2] = CONV_ATTR(CONVATTR_INDIRECT, 1); + event.xclient.data.l[3] = cap->attrAtom; + } + + XSendEvent(Tk_Display(tkwin), context->convowner, False, NoEventMask, &event); + + if (data != NULL) ckfree((char *)data); + } + + /* + *-------------------------------------------------------------- + * + * parseAttributes -- + * + * Parse attributes. + * + * Results: + * Return TCL_OK if every attributes can be parsed without + * any problems, otherwise return TCL_ERROR. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static int + parseAttributes(interp, argc, argv, ki2Ptr) + Tcl_Interp *interp; + int argc; + char **argv; + Kinput2Info *ki2Ptr; + { + int result = TCL_OK; + + ki2Ptr->num = 0; + for ( ; argc > 1; ) { + if (argv[0][0] != '-') { + Tcl_AppendResult(interp, "Warning: expected attribute name, but got \"", + *argv, "\".\n", (char *) NULL); + result = TCL_ERROR; + argv++; + argc--; + continue; + } else { + char c; + unsigned int len; + char *name = *argv + 1; + char *value = *(argv + 1); + char *new, *old; + + c = name[0]; + len = strlen(name); + new = (char *) ckalloc((unsigned) (strlen(value) + 1)); + strcpy(new, value); + if ((c == 'b') && (strncmp(name, "background", len) == 0)) { + ki2Ptr->background.specified = !None; + old = ki2Ptr->background.value; + ki2Ptr->background.value = new; + ki2Ptr->num++; + } else if ((c == 'c') && (strncmp(name, "clientArea", len) == 0) + && (len > 1)) { + ki2Ptr->clientArea.specified = !None; + old = ki2Ptr->clientArea.value; + ki2Ptr->clientArea.value = new; + ki2Ptr->num++; + } else if ((c == 'c') && (strncmp(name, "cursor", len) == 0) + && (len > 1)) { + ki2Ptr->cursor.specified = !None; + old = ki2Ptr->cursor.value; + ki2Ptr->cursor.value = new; + ki2Ptr->num++; + } else if ((c == 'e') && (strncmp(name, "eventCaptureMethod", len) == 0)) { + old = ki2Ptr->eventCaptureMethod.value; + ki2Ptr->eventCaptureMethod.specified = !None; + ki2Ptr->eventCaptureMethod.value = new; + ki2Ptr->num++; + } else if ((c == 'f') && (strncmp(name, "focusWindow", len) == 0) + && (len > 2)) { + ki2Ptr->focusWindow.specified = !None; + old = ki2Ptr->focusWindow.value; + ki2Ptr->focusWindow.value = new; + ki2Ptr->num++; + } else if ((c == 'f') && (strncmp(name, "fonts", len) == 0) + && (len > 2)) { + ki2Ptr->fonts.specified = !None; + old = ki2Ptr->fonts.value; + ki2Ptr->fonts.value = new; + ki2Ptr->num++; + } else if ((c == 'f') && (strncmp(name, "foreground", len) == 0) + && (len > 2)) { + ki2Ptr->foreground.specified = !None; + old = ki2Ptr->foreground.value; + ki2Ptr->foreground.value = new; + ki2Ptr->num++; + } else if ((c == 'i') && (strncmp(name, "inputStyle", len) == 0)) { + ki2Ptr->inputStyle.specified = !None; + old = ki2Ptr->inputStyle.value; + ki2Ptr->inputStyle.value = new; + ki2Ptr->num++; + } else if ((c == 'l') && (strncmp(name, "lineSpacing", len) == 0)) { + ki2Ptr->lineSpacing.specified = !None; + old = ki2Ptr->lineSpacing.value; + ki2Ptr->lineSpacing.value = new; + ki2Ptr->num++; + } else if ((c == 's') && (strncmp(name, "spot", len) == 0) + && (len > 1)) { + ki2Ptr->spot.specified = !None; + old = ki2Ptr->spot.value; + ki2Ptr->spot.value = new; + ki2Ptr->num++; + } else if ((c == 's') && (strncmp(name, "statusArea", len) == 0) + && (len > 1)) { + ki2Ptr->statusArea.specified = !None; + old = ki2Ptr->statusArea.value; + ki2Ptr->statusArea.value = new; + ki2Ptr->num++; + } else if ((c == 'v') && (strncmp(name, "variable", len) == 0)) { + old = ki2Ptr->variable; + ki2Ptr->variable = new; + } else { + Tcl_AppendResult(interp, "Warning: unknown attribute name \"", + *argv, "\".\n", (char *) NULL); + result = TCL_ERROR; + argv++; + argc--; + continue; + } + if (old) ckfree(old); + argv += 2; + argc -= 2; + } + } + if (argc == 1) { + Tcl_AppendResult(interp, "Warning: no attribute value for \"", + *argv, "\".\n", (char *) NULL); + result = TCL_ERROR; + } + + return result; + } + + /* + *-------------------------------------------------------------- + * + * formatAttributeInfo -- + * + * Create a valid Tcl list holding the attribute informattion + * for a sigle attribute option. + * + * Results: + * A Tcl list, dynamically allocated. The caller is expected to + * arrange for this list to be freed eventually. + * + * Side effects: + * Memory is allocated. + * + *-------------------------------------------------------------- + */ + + static char * + formatAttributeInfo(ki2Ptr, name) + Kinput2Info *ki2Ptr; + char *name; + { + char c; + unsigned int len; + char *argv[2]; + + if (*name != '-') return NULL; + + name++; + c = name[0]; + len = strlen(name); + if ((c == 'b') && (strncmp(name, "background", len) == 0)) { + argv[0] = "-background"; + argv[1] = (ki2Ptr->background.specified) ? ki2Ptr->background.value : ""; + } else if ((c == 'c') && (strncmp(name, "clientArea", len) == 0) && (len > 1)) { + argv[0] = "-clientArea"; + argv[1] = (ki2Ptr->clientArea.specified) ? ki2Ptr->clientArea.value : ""; + } else if ((c == 'c') && (strncmp(name, "cursor", len) == 0) && (len > 1)) { + argv[0] = "-cursor"; + argv[1] = (ki2Ptr->cursor.specified) ? ki2Ptr->cursor.value : ""; + } else if ((c == 'e') && (strncmp(name, "eventCaptureMethod", len) == 0)) { + argv[0] = "-eventCaptureMethod"; + argv[1] = (ki2Ptr->eventCaptureMethod.specified) ? ki2Ptr->eventCaptureMethod.value : ""; + } else if ((c == 'f') && (strncmp(name, "focusWindow", len) == 0) && (len > 2)) { + argv[0] = "-focusWindow"; + argv[1] = (ki2Ptr->focusWindow.specified) ? ki2Ptr->focusWindow.value : ""; + } else if ((c == 'f') && (strncmp(name, "fonts", len) == 0) && (len > 2)) { + argv[0] = "-fonts"; + argv[1] = (ki2Ptr->fonts.specified) ? ki2Ptr->fonts.value : ""; + } else if ((c == 'f') && (strncmp(name, "foreground", len) == 0) && (len > 2)) { + argv[0] = "-foreground"; + argv[1] = (ki2Ptr->foreground.specified) ? ki2Ptr->foreground.value : ""; + } else if ((c == 'i') && (strncmp(name, "inputStyle", len) == 0)) { + argv[0] = "-inputStyle"; + argv[1] = (ki2Ptr->inputStyle.specified) ? ki2Ptr->inputStyle.value : ""; + } else if ((c == 'l') && (strncmp(name, "lineSpacing", len) == 0)) { + argv[0] = "-lineSpacing"; + argv[1] = (ki2Ptr->lineSpacing.specified) ? ki2Ptr->lineSpacing.value : ""; + } else if ((c == 's') && (strncmp(name, "spot", len) == 0) && (len > 1)) { + argv[0] = "-spot"; + argv[1] = (ki2Ptr->spot.specified) ? ki2Ptr->spot.value : ""; + } else if ((c == 's') && (strncmp(name, "statusArea", len) == 0) && (len > 1)) { + argv[0] = "-statusArea"; + argv[1] = (ki2Ptr->statusArea.specified) ? ki2Ptr->statusArea.value : ""; + } else if ((c == 'v') && (strncmp(name, "variable", len) == 0)) { + argv[0] = "-variable"; + argv[1] = (ki2Ptr->variable) ? ki2Ptr->variable : ""; + } else { + return NULL; + } + return Tcl_Merge(2, argv); + } + + + static int + checkProtocols(dpy, window, cap) + Display *dpy; + Window window; + ConversionAtoms *cap; + { + Atom type; + int format; + unsigned long nitems; + unsigned long bytesafter; + unsigned long *data, *saveddata; + int err; + int ret; + + data = NULL; + err = XGetWindowProperty(dpy, window, cap->profileAtom, + 0L, 100L, False, + cap->typeAtom, + &type, &format, &nitems, + &bytesafter, (unsigned char **)&data); + if (err) return False; + if (format != 32 || type != cap->typeAtom) { + if (data != NULL) free((char *)data); + return False; + } + + ret = False; + saveddata = data; + while (nitems > 0) { + int code = CODE_OF_ATTR(*data); + int len = LENGTH_OF_ATTR(*data); + + data++; + nitems--; + if (nitems < len) break; + + switch (code) { + case CONVPROF_PROTOCOL_VERSION: + if (*data == cap->versionAtom) ret = True; + break; + case CONVPROF_SUPPORTED_STYLES: + break; /* XXX for now */ + default: + break; + } + data += len; + nitems -= len; + } + free((char *)saveddata); + + return ret; + } + + + /* + *-------------------------------------------------------------- + * + * finishConversion -- + * + * This procedure stops the current input conversion + * associated with the specified conversion context. + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static void + finishConversion(tkwin, context) + Tk_Window tkwin; + ConversionContext *context; + { + Tk_DeleteGenericHandler(recvConvAck, (ClientData)tkwin); + Tk_DeleteGenericHandler(getConv, (ClientData)tkwin); + Tk_DeleteEventHandler(tkwin, KeyPressMask|KeyReleaseMask, + forwardKeyEvent, (ClientData)context); + XDeleteContext(Tk_Display(tkwin), Tk_WindowId(tkwin), convertPrivContext); + } + + /* ARGSUSED */ + static int + recvConvAck(clientData, eventPtr) + ClientData clientData; + XEvent *eventPtr; + { + Tk_Window tkwin = (Tk_Window) clientData; + XClientMessageEvent *cev = &(eventPtr->xclient); + ConversionAtoms *cap; + ConversionContext *context; + + if (eventPtr->type != ClientMessage) return 0; + + cap = getAtoms(tkwin); + context = getConversionContext(tkwin); + + /* タオ、キ、、・、・ル・・ネ、ォ、ノ、ヲ、ォ・チ・ァ・テ・ッ、ケ、 */ + if (cev->window != Tk_WindowId(tkwin) || + cev->message_type != cap->notifyAtom || + cev->data.l[0] != context->convatom) { + return 0; + } + + /* + * 、ウ、ホ・マ・・ノ・鬢マ、筅ヲヘムコム、゚、ハ、ホ、ヌウー、ケ + */ + Tk_DeleteGenericHandler((Tk_GenericProc *)recvConvAck, (ClientData)tkwin); + + if (cev->data.l[2] == None) { + Tcl_AppendResult(context->interp, "Warning: selection request failed", + (char *) NULL); + callFail(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + return 1; + } + + context->forwardwin = (Window)cev->data.l[3]; + callStart(tkwin, context); + + /* + * PropertyNotify 、ネ CONVERSION_END ヘム、ホ・、・ル・・ネ・マ・・ノ・鬢 + * ナミマソ、ケ、 + */ + Tk_CreateGenericHandler((Tk_GenericProc *)getConv, (ClientData)tkwin); + + /* + * ・ュ。シ・、・ル・・ネ、ニホマ・オ。シ・ミ、ヒチ、、ソ、皃ホ・、・ル・・ネ・マ・・ノ・鬢ナミマソ、ケ、 + */ + Tk_CreateEventHandler(tkwin, KeyPressMask|KeyReleaseMask, + forwardKeyEvent, (ClientData)context); + + /* ・ラ・・ム・ニ・」フセ、・ケ・ネ・「、ケ、 */ + context->property = cev->data.l[2]; + return 1; + } + + + /* ARGSUSED */ + static int + getConv(clientData, eventPtr) + ClientData clientData; + XEvent *eventPtr; + { + Tk_Window tkwin = (Tk_Window) clientData; + ConversionAtoms *cap; + ConversionContext *context; + + /* PropertyNotify, ClientMessage, DestroyNotify ーハウー、マフオサ、ケ、 */ + if (eventPtr->type != PropertyNotify && eventPtr->type != ClientMessage + && eventPtr->type != DestroyNotify) + return 0; + + /* ・ヲ・」・・ノ・ヲ ID 、ホ・チ・ァ・テ・ッ */ + if (eventPtr->xany.window != Tk_WindowId(tkwin)) return 0; + + cap = getAtoms(tkwin); + context = getConversionContext(tkwin); + + if (eventPtr->type == ClientMessage) { + XClientMessageEvent *cev = &(eventPtr->xclient); + + /* + * ヒワナ、ヒニホマスェホサ、ホ・、・ル・・ネ、ォ、ノ、ヲ、ォ・チ・ァ・テ・ッ、ケ、 + */ + if (cev->message_type == cap->endAtom && + cev->format == 32 && + cev->data.l[0] == context->convatom) { + callEnd(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + return 1; + } + } else if (eventPtr->type == DestroyNotify) { + XDestroyWindowEvent *dev = &(eventPtr->xdestroywindow); + + if (dev->window == Tk_WindowId(tkwin)) { + callEnd(tkwin, context); + finishConversion(tkwin, context); + ckfree((char *)context); + return 0; + } + } else { /* PropertyNotify */ + XPropertyEvent *pev = &(eventPtr->xproperty); + Atom proptype; + int propformat; + unsigned long propsize, rest; + unsigned char *propvalue; + + if (context->property == None) return 0; + + /* タオ、キ、、・、・ル・・ネ、ォ、ノ、ヲ、ォ、ホ・チ・ァ・テ・ッ */ + if (pev->window != Tk_WindowId(tkwin) || + pev->atom != context->property || + pev->state != PropertyNewValue) { + return 0; + } + + /* 、筅キ・ウ。シ・・ミ・テ・ッエリソ context->inputproc 、ャ + * NULL 、ハ、鬢ミ・ラ・・ム・ニ・」、コス、ケ、、タ、ア + */ + if (context->inputproc == NULL) { + XDeleteProperty(Tk_Display(tkwin), Tk_WindowId(tkwin), context->property); + return 1; + } + + /* ・ラ・・ム・ニ・」、ォ、鯡ムエケハクサホ、シ隍スミ、ケ */ + XGetWindowProperty(Tk_Display(tkwin), Tk_WindowId(tkwin), + context->property, + 0L, 100000L, True, AnyPropertyType, + &proptype, &propformat, &propsize, &rest, + &propvalue); + + /* ・ラ・・ム・ニ・」、ホ・ソ・、・ラ。ヲ・ユ・ゥ。シ・゙・テ・ネ、ホ・チ・ァ・テ・ッ */ + if (proptype == None) { + /* ・ラ・・ム・ニ・」、ャツクコ゚、キ、ハ、ォ、テ、ソ + * 、ウ、、ママ「ツウ、キ、ニイソイ、筵ラ・・ム・ニ・」、ヒ・ヌ。シ・ソ、ャ + * ニ、、鬢、ソサ。「ーイ、ホ GetWindowProperty 、ヌ + * ハ」ソ、ホ・ヌ。シ・ソ、、ネ、テ、ニ、キ、゙、テ、ソ、「、ネ、ヒオッ、ュ、 + * スセ、テ、ニ、ウ、、マ・ィ・鬘シ、ヌ、マ、ハ、、 + */ + return 1; + } + + /* ・ウ。シ・・ミ・テ・ッ、クニ、ヨ */ + (*context->inputproc)(context->interp, tkwin, context->convatom, + proptype, propformat, + propsize, propvalue, + context->clientData); + + if (propvalue != NULL) XFree((char *)propvalue); + + return 1; + } + return 0; + } + + + static void + callStart(tkwin, context) + Tk_Window tkwin; + ConversionContext *context; + { + if (context->startendproc != NULL) { + (*context->startendproc)(context->interp, tkwin, context->convatom, + 0, context->clientData); + } + } + + + static void + callFail(tkwin, context) + Tk_Window tkwin; + ConversionContext *context; + { + if (context->startendproc != NULL) { + (*context->startendproc)(context->interp, tkwin, context->convatom, + -1, context->clientData); + } + } + + + static void + callEnd(tkwin, context) + Tk_Window tkwin; + ConversionContext *context; + { + if (context->startendproc != NULL) { + (*context->startendproc)(context->interp, tkwin, context->convatom, + 1, context->clientData); + } + } + + + static ConversionAtoms * + getAtoms(tkwin) + Tk_Window tkwin; + { + int i; + Display *disp = Tk_Display(tkwin); + ConversionAtoms *cap; + static ConversionAtoms *convatomp; + static int ndisp = 0; + #define nalloc 2 + + /* + * ・「・ネ・爨マ・ヌ・」・ケ・ラ・・、、エ、ネ、ヒー网ヲ、ホ、ヌ。「 + * ・ヌ・」・ケ・ラ・・、、エ、ネ、ヒコ、鬢ハ、ッ、ニ、マ、ハ、鬢ハ、、 + */ + + /* 、ケ、ヌ、ヒ・「・ネ・爨ャコ、鬢、ニ、、、、ォ、ノ、ヲ、ォトエ、ル、 */ + cap = convatomp; + for (i = 0; i < ndisp; i++, cap++) { + if (cap->display == disp) return cap; + } + + /* + * 、゙、タコ、鬢、ニ、、、ハ、、、ホ、ヌソキ、キ、ッコ、 + */ + if (ndisp == 0) { + /* コヌス鬢ハ、ホ、ヌ Context 、簇アサ、ヒコ、 */ + convertPrivContext = XUniqueContext(); + convatomp = (ConversionAtoms *) + malloc(sizeof(ConversionAtoms) * nalloc); + cap = convatomp; + } else if (ndisp % nalloc == 0) { + /* ・オ・、・コ、チ、荀ケ */ + convatomp = (ConversionAtoms *) + realloc((char *)convatomp, + sizeof(ConversionAtoms) * (ndisp + nalloc)); + cap = convatomp + ndisp; + } else { + cap = convatomp + ndisp; + } + + /* ・ヌ・」・ケ・ラ・・、、ホナミマソ */ + cap->display = disp; + + /* Atom 、ホコタョ */ + cap->profileAtom = Tk_InternAtom(tkwin, CONVERSION_PROFILE); + cap->typeAtom = Tk_InternAtom(tkwin, CONVERSION_ATTRIBUTE_TYPE); + cap->versionAtom = Tk_InternAtom(tkwin, PROTOCOL_VERSION); + cap->reqAtom = Tk_InternAtom(tkwin, "CONVERSION_REQUEST"); + cap->notifyAtom = Tk_InternAtom(tkwin, "CONVERSION_NOTIFY"); + cap->endAtom = Tk_InternAtom(tkwin, "CONVERSION_END"); + cap->endReqAtom = Tk_InternAtom(tkwin, "CONVERSION_END_REQUEST"); + cap->attrAtom = Tk_InternAtom(tkwin, "CONVERSION_ATTRIBUTE"); + cap->attrNotifyAtom = Tk_InternAtom(tkwin, "CONVERSION_ATTRIBUTE_NOTIFY"); + + ndisp++; + + return cap; + } + + + static ConversionContext * + getConversionContext(tkwin) + Tk_Window tkwin; + { + ConversionContext *context; + + if (XFindContext(Tk_Display(tkwin), Tk_WindowId(tkwin), + convertPrivContext, (caddr_t *)&context)) { + /* error -- ツソハャ・ウ・・ニ・ュ・ケ・ネ、ャクォ、ト、ォ、鬢ハ、ォ、テ、ソ、ソ、 */ + return NULL; + } else { + return context; + } + } + + + static long + getInputStyle(s) + char *s; + { + char c; + unsigned int len; + + c = s[0]; + len = strlen(s); + + if ((c == 'o') && (strncmp(s, "off", len) == 0) && (len > 2)) { + return CONVARG_OFFTHESPOT; + } else if ((c == 'o') && (strncmp(s, "over", len) == 0) && (len > 2)) { + return CONVARG_OVERTHESPOT; + } else if ((c == 'r') && (strncmp(s, "root", len) == 0)) { + return CONVARG_ROOTWINDOW; + } + return 0L; + } + + + static long + getCaptureMethod(s) + char *s; + { + char c; + unsigned int len; + + c = s[0]; + len = strlen(s); + + + if ((c == 'n') && (strncmp(s, "none", len) == 0)) { + return CONVARG_NONE; + } else if ((c == 'i') && (strncmp(s, "inputOnly", len) == 0)) { + return CONVARG_CREATE_INPUTONLY; + } else if ((c == 'f') && (strncmp(s, "focusSelect", len) == 0)) { + return CONVARG_SELECT_FOCUS_WINDOW; + } + return 0L; + } + + + static int + makeAttrData(interp, tkwin, ki2Ptr, datap) + Tcl_Interp *interp; + Tk_Window tkwin; + Kinput2Info *ki2Ptr; + unsigned long **datap; + { + static int max_length = 0; + #ifdef STATIC_ATTR + unsigned long buf[4096]; + #else + static unsigned long *buf = NULL; + #endif /* STATIC_ATTR */ + int length = 0; + + #ifdef STATIC_ATTR + #define ALLOC(n) ;; + #else + #ifdef ATTR_USE_REALLOC + #define ALLOC(n) \ + if (length + (n) > max_length ) { \ + max_length += (n); \ + buf = (unsigned long *)ckrealloc(buf, (unsigned)(max_length * sizeof(unsigned long))); \ + } + #else + #define ALLOC(n) \ + if (length + (n) > max_length ) { \ + unsigned long *tmp; \ + max_length += (n); \ + tmp = (unsigned long *) ckalloc((unsigned)(max_length * sizeof(unsigned long))); \ + memcpy((VOID *) tmp, (VOID *) buf, (unsigned int)(length * sizeof(unsigned long))); \ + ckfree((char *) buf); \ + buf = tmp; \ + } + #endif /* ATTR_USE_REALLOC */ + #endif /* STATIC_ATTR */ + + #ifndef STATIC_ATTR + if (buf == NULL) { + buf = (unsigned long *) ckalloc((unsigned)(max_length * sizeof(unsigned long))); + } + #endif /* !STATIC_ATTR */ + + if (ki2Ptr->inputStyle.specified) { + long style = getInputStyle(ki2Ptr->inputStyle.value); + + if (style == 0L) { + Tcl_AppendResult(interp, "Warning: bad inputStyle - \"", + ki2Ptr->inputStyle.value, "\"\n", (char *) NULL); + ki2Ptr->inputStyle.specified = None; + } else { + ALLOC(2); + buf[length] = CONV_ATTR(CONVATTR_INPUT_STYLE, 1); + buf[length+1] = style; + length += 2; + } + } + if (ki2Ptr->focusWindow.specified) { + Tk_Window win = Tk_NameToWindow(interp, ki2Ptr->focusWindow.value, tkwin); + + if (win == NULL ) { + Tcl_AppendResult(interp, "Warning: bad focusWindow - \"", + ki2Ptr->focusWindow.value, "\"\n", (char *) NULL); + ki2Ptr->focusWindow.specified = None; + } else { + ALLOC(2); + buf[length] = CONV_ATTR(CONVATTR_FOCUS_WINDOW, 1); + buf[length+1] = (unsigned long) Tk_WindowId(win); + length += 2; + } + } + if (ki2Ptr->spot.specified) { + int xargc; + char **xargv; + int spotX, spotY; + + if (Tcl_SplitList(interp, ki2Ptr->spot.value, &xargc, &xargv) != TCL_OK) { + ki2Ptr->spot.specified = None; + } else { + if (xargc != 2 + || Tcl_GetInt(interp, xargv[0], &spotX) != TCL_OK + || Tcl_GetInt(interp, xargv[1], &spotY) != TCL_OK) { + Tcl_AppendResult(interp, "Warning: bad spot - \"", + ki2Ptr->spot.value, "\"\n", (char *) NULL); + ki2Ptr->spot.specified = None; + } else { + ALLOC(2); + buf[length] = CONV_ATTR(CONVATTR_SPOT_LOCATION, 1); + buf[length+1] = (spotX << 16) | (spotY & 0xffff); + length += 2; + } + ckfree((char *) xargv); + } + } + if (ki2Ptr->foreground.specified && ki2Ptr->background.specified) { + XColor *fgPtr, *bgPtr; + + fgPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(ki2Ptr->foreground.value)); + bgPtr = Tk_GetColor(interp, tkwin, Tk_GetUid(ki2Ptr->background.value)); + if (fgPtr == NULL) { + Tcl_AppendResult(interp, "Warning: bad foreground - \"", + ki2Ptr->foreground.value, "\"\n", (char *) NULL); + ki2Ptr->foreground.specified = None; + } + if (bgPtr == NULL) { + Tcl_AppendResult(interp, "Warning: bad background - \"", + ki2Ptr->background.value, "\"\n", (char *) NULL); + ki2Ptr->background.specified = None; + } + if (fgPtr && bgPtr) { + ALLOC(3); + buf[length] = CONV_ATTR(CONVATTR_COLOR, 2); + buf[length+1] = fgPtr->pixel; + buf[length+2] = bgPtr->pixel; + length += 3; + } + } + if (ki2Ptr->eventCaptureMethod.specified) { + long method = getCaptureMethod(ki2Ptr->eventCaptureMethod.value); + + if (method == 0L) { + Tcl_AppendResult(interp, "Warning: bad eventCaptureMethod - \"", + ki2Ptr->eventCaptureMethod.value, "\"\n", (char *) NULL); + ki2Ptr->eventCaptureMethod.specified = None; + } else { + ALLOC(2); + buf[length] = CONV_ATTR(CONVATTR_EVENT_CAPTURE_METHOD, 1); + buf[length+1] = method; + length += 2; + } + } + if (ki2Ptr->lineSpacing.specified) { + int spacing; + + if (Tcl_GetInt(interp, ki2Ptr->lineSpacing.value, &spacing) != TCL_OK) { + Tcl_AppendResult(interp, "Warning: bad lineSpacing - \"", + ki2Ptr->lineSpacing.value, "\"\n", (char *) NULL); + ki2Ptr->lineSpacing.specified = None; + } else { + ALLOC(2); + buf[length] = CONV_ATTR(CONVATTR_LINE_SPACING, 1); + buf[length+1] = spacing; + length += 2; + } + } + if (ki2Ptr->clientArea.specified) { + int xargc; + char **xargv; + int x, y, width, height; + + if (Tcl_SplitList(interp, ki2Ptr->clientArea.value, &xargc, &xargv) != TCL_OK) { + ki2Ptr->clientArea.specified = None; + } else { + if (xargc != 4 + || Tcl_GetInt(interp, xargv[0], &x) != TCL_OK + || Tcl_GetInt(interp, xargv[1], &y) != TCL_OK + || Tcl_GetInt(interp, xargv[2], &width) != TCL_OK + || Tcl_GetInt(interp, xargv[3], &height) != TCL_OK) { + Tcl_AppendResult(interp, "Warning: bad clientArea - \"", + ki2Ptr->clientArea.value, "\"\n", (char *) NULL); + ki2Ptr->clientArea.specified = None; + } else { + ALLOC(3); + buf[length] = CONV_ATTR(CONVATTR_CLIENT_AREA, 2); + buf[length+1] = (x << 16) | (y & 0xffff); + buf[length+2] = (width << 16) | (height & 0xffff); + length += 3; + } + ckfree((char *) xargv); + } + } + if (ki2Ptr->statusArea.specified) { + int xargc; + char **xargv; + int x, y, width, height; + + if (Tcl_SplitList(interp, ki2Ptr->statusArea.value, &xargc, &xargv) != TCL_OK) { + ki2Ptr->statusArea.specified = None; + } else { + if (xargc != 4 + || Tcl_GetInt(interp, xargv[0], &x) != TCL_OK + || Tcl_GetInt(interp, xargv[1], &y) != TCL_OK + || Tcl_GetInt(interp, xargv[2], &width) != TCL_OK + || Tcl_GetInt(interp, xargv[3], &height) != TCL_OK) { + Tcl_AppendResult(interp, "Warning: bad statusArea - \"", + ki2Ptr->statusArea.value, "\"\n", (char *) NULL); + ki2Ptr->statusArea.specified = None; + } else { + ALLOC(3); + buf[length] = CONV_ATTR(CONVATTR_STATUS_AREA, 2); + buf[length+1] = (x << 16) | (y & 0xffff); + buf[length+2] = (width << 16) | (height & 0xffff); + length += 3; + } + ckfree((char *) xargv); + } + } + if (ki2Ptr->cursor.specified) { + Cursor cursor = (Cursor) Tk_GetCursor(interp, tkwin, + Tk_GetUid(ki2Ptr->cursor.value)); + + if (cursor == None) { + Tcl_AppendResult(interp, "Warning: bad cursor - \"", + ki2Ptr->cursor.value, "\"\n", (char *) NULL); + ki2Ptr->cursor.specified = None; + } else { + ALLOC(2); + buf[length] = CONV_ATTR(CONVATTR_CURSOR, 1); + buf[length+1] = cursor; + length += 2; + } + } + if (ki2Ptr->fonts.specified) { + int xargc; + char **xargv; + + if (Tcl_SplitList(interp, ki2Ptr->fonts.value, &xargc, &xargv) == TCL_OK) { + XFontStruct *fontPtr; + int nfonts, i; + unsigned long atom; + + #ifdef OLD_TK4X + ALLOC(xargc+1); + #endif /* OLD_TK4X */ + nfonts = 0; + for (i = 0; i < xargc; i++) { + #ifdef OLD_TK4X + fontPtr = Tk_GetFontStruct(interp, tkwin, Tk_GetUid(xargv[i])); + if (fontPtr != NULL + && XGetFontProperty(fontPtr, XA_FONT, &atom)) { + buf[length + ++nfonts] = atom; + } else { + Tcl_AppendResult(interp, "Warning: bad font - \"", + xargv[i], "\"\n", (char *) NULL); + } + #else + + #define doALLOC(n) \ + if (nfonts == 0) { \ + ALLOC((n)+1); \ + length += 2; \ + } else { \ + ALLOC(1); \ + length++; \ + } \ + nfonts++; \ + buf[oLength] = CONV_ATTR(CONVATTR_FONT_ATOMS, nfonts); \ + buf[oLength + nfonts] = atom; + + int oLength = length; + Tk_Font tkfont = Tk_GetFont(interp, tkwin, Tk_GetUid(xargv[i])); + if (tkfont != NULL) { + if (Tk_FontType(tkfont) == TK_FONT_COMPOUND) { + fontPtr = TkpGetAsciiFontStruct(tkfont); + if (fontPtr != NULL + && XGetFontProperty(fontPtr, XA_FONT, &atom)) { + doALLOC(1); + } + fontPtr = TkpGetKanjiFontStruct(tkfont); + if (fontPtr != NULL + && XGetFontProperty(fontPtr, XA_FONT, &atom)) { + doALLOC(1); + } + } else { + Tk_Font defFont; + fontPtr = TkpGetFontStruct(tkfont); + if (fontPtr != NULL + && XGetFontProperty(fontPtr, XA_FONT, &atom)) { + doALLOC(1); + } + defFont = TkpGetDefaultFontByDisplay(Tk_Display(tkwin)); + if (defFont != NULL) { + fontPtr = TkpGetFontStruct(defFont); + if (fontPtr != NULL + && XGetFontProperty(fontPtr, XA_FONT, &atom)) { + doALLOC(1); + } + } + } + } else { + Tcl_AppendResult(interp, "Warning: bad font - \"", + xargv[i], "\"\n", (char *) NULL); + } + Tk_FreeFont(tkfont); + #undef doALLOC + #endif /* OLD_TK4X */ + } + #ifdef OLD_TK4X + if (nfonts == 0) { + ki2Ptr->fonts.specified = None; + } else { + buf[length] = CONV_ATTR(CONVATTR_FONT_ATOMS, nfonts); + length += nfonts+1; + } + #else + if (nfonts == 0) { + ki2Ptr->fonts.specified = None; + } + #endif /* OLD_TK4X */ + ckfree((char *) xargv); + } + } + + *datap = (unsigned long *) ckalloc((unsigned)(length * sizeof(unsigned long))); + memcpy((VOID *) *datap, (VOID *) buf, (unsigned int)(length * sizeof(unsigned long))); + + return length; + #undef ALLOC + } + + /* + *-------------------------------------------------------------- + * + * forwardKeyEvent -- + * + * This procedure forwards the key events to the input server + * (kinput2). + * + * Results: + * None. + * + * Side effects: + * This procedure may change the contents of the event. + * + *-------------------------------------------------------------- + */ + + static void + forwardKeyEvent(clientdata, event) + ClientData clientdata; + XEvent *event; + { + ConversionContext *context = (ConversionContext *)clientdata; + Display *dpy = event->xany.display; + Window w = context->forwardwin; + Tk_ErrorHandler handle; + + /* + * If the event is a non-synthetic Key event and the target + * window of the input server is not None, we forward the event + * to the window. + * Checking whether the event is synthetic or not is necessary + * because the input server might send back the event we've just + * forwarded, and forwarding those events sent back by the server + * can cause an infinite event loop. + */ + if (w != None && !event->xany.send_event && + (event->type == KeyPress || event->type == KeyRelease)) { + Window orig_win = event->xkey.window; + + event->xkey.window = w; + handle = Tk_CreateErrorHandler(dpy, -1, -1, -1, + (Tk_ErrorProc *)stopForwarding, + clientdata); + (void)XSendEvent(dpy, w, False, KeyPressMask, event); + Tk_DeleteErrorHandler(handle); + event->xkey.window = orig_win; + + /* + * Since this event has been sent to the input server, + * we must stop the further processing of the event. + * We have determined to change the keycode field of + * the event to an invalid value, because there's no + * appropriate way to do it. + * The range of the valid keycode is 8-255, and keycode 0 + * is used by the X11R5 I18N as a special code, so we've + * chosen 1. + */ + event->xkey.keycode = 1; + } + } + + /* + *-------------------------------------------------------------- + * + * stopForwarding -- + * + * This procedure stops forwarding the key events. + * It is intended to use as an error handler which is + * installed by Tk_CreateErrorHandler(). + * + * Results: + * None. + * + * Side effects: + * None. + * + *-------------------------------------------------------------- + */ + + static int + stopForwarding(clientdata, errEvent) + ClientData clientdata; + XErrorEvent *errEvent; + { + ConversionContext *context = (ConversionContext *)clientdata; + + if (errEvent->type == BadWindow) { + callEnd(context->tkwin, context); + finishConversion(context->tkwin, context); + ckfree((char *)context); + } + return 0; + } + + #endif /* KANJI && KINPUT2 */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkKinput2.h ./unix/tkKinput2.h *** ../../tk8.0.5/unix/tkKinput2.h Thu Jan 1 09:00:00 1970 --- ./unix/tkKinput2.h Fri Mar 12 00:39:18 1999 *************** *** 0 **** --- 1,323 ---- + /* + * tkKinput2.h -- + * + * Declarations for the kinput2. + * + * Copyright 1988, 1993, 1999 Software Research Associates, Inc. + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * $Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/unix/tkKinput2.h,v 1.4 1999/03/11 15:39:18 m-hirano Exp $ + */ + + #ifndef _TKKINPUT2 + #define _TKKINPUT2 + + /* ハムエケ・オ。シ・ミ、ホ・ラ・・ユ・。・、・、ャニ、・ラ・・ム・ニ・」フセ */ + #define CONVERSION_PROFILE "_CONVERSION_PROFILE" + + /* ハムエケ・オ。シ・ミ、ホ・ラ・・ユ・。・、・、ホ・ラ・・ム・ニ・」、ネハムエケツータュ、ホ・ラ・・ム・ニ・」、ホ・ソ・、・ラ */ + #define CONVERSION_ATTRIBUTE_TYPE "_CONVERSION_ATTRIBUTE_TYPE" + + /* ・ラ・・ネ・ウ・・ミ。シ・ク・逾フセ */ + #define PROTOCOL_VERSION "PROTOCOL-2.0" + + #define CONV_ATTR(code,len) ((unsigned long)((code)<<16)+(len)) + + #define UPPER16U(data) (((data)>>16)&0xffff) + #define UPPER16S(data) ((short)(((data)>>16)&0xffff)) + #define LOWER16U(data) ((data)&0xffff) + #define LOWER16S(data) ((short)((data)&0xffff)) + + #define CODE_OF_ATTR(head) UPPER16U(head) + #define LENGTH_OF_ATTR(head) LOWER16U(head) + + /* + * Conversion Profile Codes + */ + + #define CONVPROF_PROTOCOL_VERSION 1 + #define CONVPROF_SUPPORTED_STYLES 2 + #define CONVPROF_SUPPORTED_EXTENSIONS 3 + #define CONVPROF_EXTENSION_DATA 4 + + /* + * Standard Conversion Attribute Codes (0-255) + */ + + /* 0-127: can be specified at any time (startup and during conversion) */ + #define CONVATTR_NONE 0 + #define CONVATTR_INDIRECT 1 + #define CONVATTR_FOCUS_WINDOW 2 + #define CONVATTR_SPOT_LOCATION 3 + #define CONVATTR_CLIENT_AREA 4 + #define CONVATTR_STATUS_AREA 5 + #define CONVATTR_COLORMAP 6 + #define CONVATTR_COLOR 7 + #define CONVATTR_BACKGROUND_PIXMAP 8 + #define CONVATTR_LINE_SPACING 9 + #define CONVATTR_FONT_ATOMS 10 + #define CONVATTR_CURSOR 11 + + /* 128-255: can be specified only at startup time */ + #define CONVATTR_INPUT_STYLE 128 + #define CONVATTR_EVENT_CAPTURE_METHOD 129 + #define CONVATTR_USE_EXTENSION 255 + + /* argument for CONVATTR_INPUT_STYLE and CONVPROP_SUPPORTED_STYLES */ + #define CONVARG_ROOTWINDOW 1L + #define CONVARG_OFFTHESPOT 2L + #define CONVARG_OVERTHESPOT 4L + + /* argument for CONVATTR_EVENT_CAPTURE_METHOD */ + #define CONVARG_NONE 0L + #define CONVARG_CREATE_INPUTONLY 1L + #define CONVARG_SELECT_FOCUS_WINDOW 2L + + /* + * ・ラ・・ユ・。・、・・ヌ。シ・ソ / ハムエケツータュ・ヌ。シ・ソ、ホノスクスハヒ。 + * + * ハムエケ・オ。シ・ミ、ホニテタュ、ノス、ケ・ラ・・ユ・。・、・・ヌ。シ・ソ、ネ。「ハムエケ、ヒエリ、ケ、ツータュ、サリト熙ケ + * 、ハムエケツータュ・ヌ。シ・ソ、マカヲトフ、ホ・ユ・ゥ。シ・゙・テ・ネ、ヘム、、、。」 + * + * クト。ケ、ホ・ヌ。シ・ソ、マ 32bitテヘ、ホヌロホ、ヌノスクス、オ、、。」コヌス鬢ホ 1・。シ・ノ、マ・リ・テ・タ、ヌ。「 + * 、ス、、ヒ 0・。シ・ノーハセ螟ホ・ヌ。シ・ソ、ャツウ、ッ。」・リ・テ・タ、ホセ蟆フ 16bit 、マ、ス、ホ・ラ・・ユ・。・、 + * ・ / ハムエケツータュ、ホ・ウ。シ・ノ、ノス、キ。「イシーフ 16 bit 、マツウ、ッ・ヌ。シ・ソ、ホ・。シ・ノソ + * (32bit テアーフ) 、ノス、ケ。」 + * + * +----------------+----------------+ + * | Code (16bit) | Length (16bit) | + * +----------------+----------------+ + * | Data0 | + * +---------------------------------+ + * | ..... | + * +---------------------------------+ + * | DataN | + * +---------------------------------+ + * + * シツコン、ホ・ラ・・ユ・。・、・・ヌ。シ・ソ、萍ムエケツータュ・ヌ。シ・ソ、マ、ウ、ホ・ヌ。シ・ソ、ャ、、、ッ、ト、ォマ「ツウ、キ + * 、ソ、筅ホ、ヌ、「、。」 + */ + + /* + * ・ラ・・ユ・。・、・・ヌ。シ・ソ + * + * ・ラ・・ユ・。・、・・ヌ。シ・ソヘム、ホ・ウ。シ・ノ、マシ。、ホ 4シホ爨ャトオチ、オ、、ニ、、、。」ハムエケツータュ + * ・ヌ。シ・ソ、ネーロ、ハ、遙「・ラ・鬣、・ル。シ・ネヘム、ホ・ウ。シ・ノホホー隍ハ、ノ、マヘムーユ、オ、、ニ、、、ハ、、。」 + * + * Protocol Version + * code: 1 + * data-length: 1 + * data[0]: + * CARD32: protocol version atom ("PROTOCOL-2.0") + * + * ・ヌ。シ・ソ、マハムエケ・オ。シ・ミ、ホ・ラ・・ネ・ウ・・ミ。シ・ク・逾、ノス、ケ・「・ネ・爨ヌ、「、。」、ウ、ウ + * 、ヌトオチ、オ、、ニ、、、・ラ・・ネ・ウ・、ホ・ミ。シ・ク・逾、マ "PROTOCOL-2.0" 、ヌ、「、。」 + * + * Supported Styles + * code: 2 + * data-length: 1 + * data[0]: + * CARD32: input styles + * + * ・ヌ。シ・ソ、マハムエケ・オ。シ・ミ、ャ・オ・ン。シ・ネ、ケ、ニホマ・ケ・ソ・、・、ノス、ケ。」・オ・ン。シ・ネ、ケ、 + * ニホマ・ケ・ソ・、・、ホテヘ、ホ bitwise-or 、ヌ、「、。」 + * + * Supported Extensions + * code: 3 + * data-length: N + * data[0]: + * CARD32: extension atom 1 (Atom) + * ... + * data[N-1]: + * CARD32: extension atom N (Atom) + * + * ・ヌ。シ・ソ、マハムエケ・オ。シ・ミ、ャ・オ・ン。シ・ネ、ケ、ウネト・、ノス、ケ・「・ネ・爨ホ・・ケ・ネ、ヌ、「、。」 + * + * Extension Data + * code: 4 + * data-length: N + * data[0]: + * CARD32: extension atom (Atom) + * data[1] - data[N-1]: + * extension specific data + * + * ・ヌ。シ・ソ、マウネト・ニネシォ、ヒトオチ、キ、ソ・ラ・・ユ・。・、・・ヌ。シ・ソ、ヌ、「、。」ノクス爭ラ・・ネ・ウ + * ・、ネ、キ、ニ、マ・ヌ。シ・ソ、ホタ霹ャ、ヒウネト・・「・ネ・ (、ウ、、マSupported Extensions + * 、ヒサリト熙オ、、ソ、筅ホ、ヌ、ハ、ア、、ミ、ハ、鬢ハ、、)、、ト、ア、、ウ、ネ、オャト熙ケ、、タ、ア、ヌ。「 + * 、ス、ホク螟ホ・ヌ。シ・ソ、ヒエリ、キ、ニ、マータレオャト熙キ、ハ、、。」 + * + * ・ッ・鬣、・「・・ネツヲ、ホフオヘム、ホコョヘ、ヒノ、ー、ソ、癸「Protocol Version 、ネ Supported + * Styles、ホケ猯ワ、マノャ、コ、ハ、ア、、ミ、ハ、鬢ハ、、。」、゙、ソ。「Extension Data ーハウー、マ・ラ・・ユ・。 + * ・、・・ヌ。シ・ソ、ホテ讀ヒニア、ク・ウ。シ・ノ、ホ・ヌ。シ・ソ、ャハ」ソ、「、テ、ニ、マ、ハ、鬢ハ、、。」 + */ + + /* + * ハムエケツータュ・ヌ。シ・ソ + * + * ツータュ・ウ。シ・ノ、ホ、ヲ、チ。「0 、ォ、 255 、゙、ヌ、マノクス爭ラ・・ネ・ウ・、ャサネヘム、ケ、、筅ホ、ヌ。「クス + * コ゚ツータュ、ャウ荀ソカ、鬢、ニ、、、ハ、、、ォ、鬢ネ、、、テ、ニセ。シ熙ヒサネヘム、キ、ニ、マ、ハ、鬢ハ、、。」、ス、ホ + * 、隍ヲ、ハフワナェ、ホ、ソ、眥ータュ・ウ。シ・ノ 256 、ォ、 65535 、ャ・ラ・鬣、・ル。シ・ネ・ウ。シ・ノウネト・ホホ + * ー隍ネ、キ、ニヘムーユ、オ、、ニ、、、。」、ソ、タ、キ、ウ、ホホホー隍ホサネヘム、ヒナ、ソ、テ、ニ、マ、「、鬢ォ、ク、皃ス + * 、ホウネト・・ウ。シ・ノ、サネヘム、ケ、、ウ、ネ、 Use Extension (イシオュサイセネ) 、ヘム、、、ニ、「、鬢ォ + * 、ク、眤クタ、ケ、ノャヘラ、ャ、「、。」 + * + * ツータュ・ヌ。シ・ソ、ホサリトハヒ。、ヒ、マ。「ハムエケウォサマサ、ヒサリト熙ケ、ハヒ。、ネ。「ハムエケテ讀ヒサリト熙ケ + * 、ハヒ。、ホ 2トフ、熙ャ、「、、ャ。「ツータュ・ウ。シ・ノ、ヒ、隍テ、ニ、マハムエケウォサマサ、ヒ、キ、ォサリト熙ヌ、ュ + * 、ハ、、、筅ホ、ャ、「、。」、ス、ウ、ヌ。「0-255 、ホノクス爭ウ。シ・ノ、ホ、ヲ、チ。「0 、ォ、 127 、゙、ヌ、マハム + * エケウォサマサ、ヌ、簗ムエケテ讀ヌ、篏リト熙ヌ、ュ、、筅ホ。「128 、ォ、 255 、゙、ヌ、マハムエケウォサマサ、ヒ + * 、キ、ォサリト熙ヌ、ュ、ハ、、、筅ホ。「、ヒハャ、ア、ニ、「、。」ウネト・・ウ。シ・ノ、ヒ、ト、、、ニ、マニテ、ヒ、ウ、ホ、隍ヲ + * 、ハカ靆フ、マト熙皃ハ、、。」 + * + * 、ウ、ホ・ラ・・ネ・ウ・、ヌトオチ、オ、、ツータュ・ウ。シ・ノ、マシ。、ホトフ、熙ヌ、「、。」 + * + * -- ハムエケウォサマサ、ヒ、筍「ハムエケナモテ讀ヒ、篏リト熙ヌ、ュ、、筅ホ -- + * + * No Operation: + * code: 0 + * data-length: N (could be 0) + * data: anything + * + * イソ、筅キ、ハ、、。」・ラ・・ム・ニ・」、ホ、「、ノハャ、・ケ・ュ・テ・ラ、オ、サ、、ホ、ヒハリヘ。」 + * + * Indirect Attribute: + * code: 1 + * data-length: 1 + * data[0]: + * CARD32: property name (Atom) + * + * サリト熙オ、、ソ・ラ・・ム・ニ・」、ヒスセ、テ、ニツータュ、タ゚ト熙ケ、。」CONVERSION_ATTRIBUTE + * ・、・ル・・ネ、ヌハ」ソ、ホツータュ・ヌ。シ・ソ、タ゚ト熙キ、ソ、、サ、茖「・、・ル・・ネ、ヒツータュ・ヌ。シ・ソ、ャ + * ニ、タレ、鬢ハ、、サ、ヒサネヘム、ケ、。」 + * + * Focus Window: + * code: 2 + * data-length: 1 + * data[0]: + * CARD32: focus window (Window) + * + * ・ユ・ゥ。シ・ォ・ケ・ヲ・」・・ノ・ヲ、サリト熙ケ、。」 + * + * Spot Location: + * data-length: 1 + * data[0]: + * INT16(upper 16bit): X + * INT16(lower 16bit): Y + * + * ・ケ・ン・テ・ネ・・ア。シ・キ・逾、サリト熙ケ、。」・ル。シ・ケ・鬣、・、ホウォサマナタ、ヌサリト熙ケ、。」 + * + * Client Area: + * data-length: 2 + * data[0]: + * INT16(upper 16bit): X + * INT16(lower 16bit): Y + * data[1]: + * CARD16(upper 16bit): Width + * CARD16(lower 16bit): Height + * + * ハムエケ・ニ・ュ・ケ・ネノスシィホホー隍サリト熙ケ、。」 + * + * Status Area: + * data-length: 2 + * data[0]: + * INT16(upper 16bit): X + * INT16(lower 16bit): Y + * data[1]: + * CARD16(upper 16bit): Width + * CARD16(lower 16bit): Height + * + * ・ケ・ニ。シ・ソ・ケノスシィホホー隍サリト熙ケ、。」 + * + * Colormap: + * data-length: 1 + * data[0]: + * CARD32: colormap (XID) + * + * ・ォ・鬘シ・゙・テ・ラ ID 、サリト熙ケ、。」 + * + * Color: + * data-length: 2 + * data[0]: + * CARD32: foreground pixel + * data[1]: + * CARD32: background pixel + * + * ・ユ・ゥ・「・ー・鬣ヲ・・ノ、ネ・ミ・テ・ッ・ー・鬣ヲ・・ノ、ホ・ヤ・ッ・サ・テヘ、サリト熙ケ、。」 + * + * Background Pixmap: + * data-length: 1 + * data[0]: + * CARD32: background pixmap (Pixmap) + * + * ・ミ・テ・ッ・ー・鬣ヲ・・ノ、ホ Pixmap ID 、サリト熙ケ、。」 + * + * Line Spacing: + * data-length: 1 + * data[0]: + * CARD32: line spacing + * + * ケヤエヨ、サリト熙ケ、。」・ル。シ・ケ・鬣、・エヨ、ホオホ・、ヌサリト熙ケ、。」 + * + * Font Atoms: + * data-length: N (>0) + * data[0]: + * CARD32: font atom 1 (Atom) + * ... + * data[N-1]: + * CARD32: font atom N (Atom) + * + * サネヘム、ケ、・ユ・ゥ・・ネ、ホ "FONT" ・「・ネ・爨ホ・・ケ・ネ、サリト熙ケ、。」 + * + * Cursor: + * data-length: 1 + * data[0]: + * CARD32: cursor (Cursor) + * + * ・ォ。シ・ス・ ID 、サリト熙ケ、。」 + * + * -- ハムエケウォサマサ、ホ、゚サリト熙ヌ、ュ、、筅ホ -- + * + * Input Style: + * data-length: 1 + * data[0]: + * CARD32: input style + * + * ニホマハヒ。、サリト熙ケ、。」 + * ・ヌ・ユ・ゥ・・ネ、マ Root Window Style 、ヌ、「、。」 + * + * Event Capture Method: + * data-length: 1 + * data[0]: + * CARD32: event capture method + * + * ・ッ・鬣、・「・・ネ・ヲ・」・・ノ・ヲ、ォ、鬢ホ・、・ル・・ネ、ホシ霹タハヒ。、サリト熙ケ、。」・ヌ・ユ・ゥ + * ・・ネ、マ・ッ・鬣、・「・・ネ・ヲ・」・・ノ・ヲ、ホチー、ヒ InputOnly ・ヲ・」・・ノ・ヲ、コ、テ、ニ + * 、ス、ホ・ュ。シ・、・ル・・ネ、・サ・・ッ・ネ、ケ、、ネ、、、ヲ、筅ホ、ヌ、「、。」ツセ、ホハヒ。、ネ、キ、ニ、マ。「 + * ・ユ・ゥ。シ・ォ・ケ・ヲ・」・・ノ・ヲ (・ユ・ゥ。シ・ォ・ケ・ヲ・」・・ノ・ヲ、ャサリト熙オ、、ニ、、、ハ、ア、、ミ + * ・ッ・鬣、・「・・ネ・ヲ・」・・ノ・ヲ) 、ホ・ュ。シ・、・ル・・ネ、トセタワ・サ・・ッ・ネ、ケ、 (、ウ、ホセ + * ケ遑「ハムエケテ讀マ・ッ・鬣、・「・・ネ、マ・ュ。シ・、・ル・・ネ、フオサ、キ、ハ、ッ、ニ、マ、ハ、鬢ハ、、) + * 、筅ホ、ネ。「イソ、筅キ、ハ、、。「、ト、゙、ハムエケテ讀ホ・ッ・鬣、・「・・ネ、マ・ュ。シ・、・ル・・ネ、・ユ + * ・・・ネ・ィ・・ノ、ヒ SendEvent 、キ、ハ、ッ、ニ、マ、ハ、鬢ハ、、。「、ネ、、、ヲハヒ。、ャ、「、。」 + * + * Use Extension: + * data-length: N + * data[0]: + * CARD32: extension atom 1 (Atom) + * ... + * data[N-1]: + * CARD32: extension atom N (Atom) + * + * 、ウ、ホツータュタ゚ト熙ヌサネヘム、オ、、ウネト・、サリト熙ケ、。」、ウ、ウ、ヌサリト熙ケ、ウネト・、マ・オ。シ + * ・ミ、ャ・オ・ン。シ・ネ、キ、ニ、、、、筅ホ。「、ト、゙、・ラ・・ユ・。・、・・ヌ。シ・ソテ讀ホSupported + * Extensions 、ヒス、ォ、、ソウネト・、ヌ、ハ、ア、、ミ、ハ、鬢ハ、、。」 + */ + + #endif /* _TKKINPUT2 */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixButton.c ./unix/tkUnixButton.c *** ../../tk8.0.5/unix/tkUnixButton.c Tue Sep 15 03:23:55 1998 --- ./unix/tkUnixButton.c Fri Mar 12 00:39:19 1999 *************** *** 439,445 **** --- 439,452 ---- width = butPtr->textWidth; height = butPtr->textHeight; + #ifdef TK_KANJI_OK + { + wchar wTmp = '0'; + avgWidth = Tk_TextWidth(butPtr->tkfont, &wTmp, 1); + } + #else avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); + #endif /* TK_KANJI_OK */ Tk_GetFontMetrics(butPtr->tkfont, &fm); if (butPtr->width > 0) { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixCursor.c ./unix/tkUnixCursor.c *** ../../tk8.0.5/unix/tkUnixCursor.c Tue Sep 15 03:23:55 1998 --- ./unix/tkUnixCursor.c Fri Mar 12 00:39:20 1999 *************** *** 323,328 **** --- 323,333 ---- badString: + #ifdef BUGFIX + if (argv != NULL) { + ckfree((char *) argv); + } + #endif /* BUGFIX */ Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", (char *) NULL); return NULL; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixDefault.h ./unix/tkUnixDefault.h *** ../../tk8.0.5/unix/tkUnixDefault.h Tue Sep 15 03:23:55 1998 --- ./unix/tkUnixDefault.h Fri Mar 12 00:39:20 1999 *************** *** 57,63 **** --- 57,67 ---- #define DEF_BUTTON_DISABLED_FG_MONO "" #define DEF_BUTTON_FG BLACK #define DEF_CHKRAD_FG DEF_BUTTON_FG + #ifdef KANJI + #define DEF_BUTTON_FONT "Mincho:Helvetica-Bold-12" + #else #define DEF_BUTTON_FONT "Helvetica -12 bold" + #endif /* KANJI */ #define DEF_BUTTON_HEIGHT "0" #define DEF_BUTTON_HIGHLIGHT_BG NORMAL_BG #define DEF_BUTTON_HIGHLIGHT BLACK *************** *** 133,139 **** --- 137,147 ---- #define DEF_ENTRY_BORDER_WIDTH "2" #define DEF_ENTRY_CURSOR "xterm" #define DEF_ENTRY_EXPORT_SELECTION "1" + #ifdef KANJI + #define DEF_ENTRY_FONT "Mincho:Helvetica-12" + #else #define DEF_ENTRY_FONT "Helvetica -12" + #endif /* KANJI */ #define DEF_ENTRY_FG BLACK #define DEF_ENTRY_HIGHLIGHT_BG NORMAL_BG #define DEF_ENTRY_HIGHLIGHT BLACK *************** *** 189,195 **** --- 197,207 ---- #define DEF_LISTBOX_BORDER_WIDTH "2" #define DEF_LISTBOX_CURSOR "" #define DEF_LISTBOX_EXPORT_SELECTION "1" + #ifdef KANJI + #define DEF_LISTBOX_FONT "Mincho:Helvetica-Bold-12" + #else #define DEF_LISTBOX_FONT "Helvetica -12 bold" + #endif /* KANJI */ #define DEF_LISTBOX_FG BLACK #define DEF_LISTBOX_HEIGHT "10" #define DEF_LISTBOX_HIGHLIGHT_BG NORMAL_BG *************** *** 250,256 **** --- 262,272 ---- #define DEF_MENU_CURSOR "arrow" #define DEF_MENU_DISABLED_FG_COLOR DISABLED #define DEF_MENU_DISABLED_FG_MONO "" + #ifdef KANJI + #define DEF_MENU_FONT "Mincho:Helvetica-Bold-12" + #else #define DEF_MENU_FONT "Helvetica -12 bold" + #endif /* KANJI */ #define DEF_MENU_FG BLACK #define DEF_MENU_POST_COMMAND "" #define DEF_MENU_RELIEF "raised" *************** *** 279,285 **** --- 295,305 ---- #define DEF_MENUBUTTON_DIRECTION "below" #define DEF_MENUBUTTON_DISABLED_FG_COLOR DISABLED #define DEF_MENUBUTTON_DISABLED_FG_MONO "" + #ifdef KANJI + #define DEF_MENUBUTTON_FONT "Mincho:Helvetica-Bold-12" + #else #define DEF_MENUBUTTON_FONT "Helvetica -12 bold" + #endif /* KANJI */ #define DEF_MENUBUTTON_FG BLACK #define DEF_MENUBUTTON_HEIGHT "0" #define DEF_MENUBUTTON_HIGHLIGHT_BG NORMAL_BG *************** *** 311,317 **** --- 331,341 ---- #define DEF_MESSAGE_BORDER_WIDTH "2" #define DEF_MESSAGE_CURSOR "" #define DEF_MESSAGE_FG BLACK + #ifdef KANJI + #define DEF_MESSAGE_FONT "Mincho:Helvetica-Bold-12" + #else #define DEF_MESSAGE_FONT "Helvetica -12 bold" + #endif /* KANJI */ #define DEF_MESSAGE_HIGHLIGHT_BG NORMAL_BG #define DEF_MESSAGE_HIGHLIGHT BLACK #define DEF_MESSAGE_HIGHLIGHT_WIDTH "0" *************** *** 337,343 **** --- 361,371 ---- #define DEF_SCALE_COMMAND "" #define DEF_SCALE_CURSOR "" #define DEF_SCALE_DIGITS "0" + #ifdef KANJI + #define DEF_SCALE_FONT "Mincho:Helvetica-Bold-12" + #else #define DEF_SCALE_FONT "Helvetica -12 bold" + #endif /* KANJI */ #define DEF_SCALE_FG_COLOR BLACK #define DEF_SCALE_FG_MONO BLACK #define DEF_SCALE_FROM "0" *************** *** 399,405 **** --- 427,437 ---- #define DEF_TEXT_CURSOR "xterm" #define DEF_TEXT_FG BLACK #define DEF_TEXT_EXPORT_SELECTION "1" + #ifdef KANJI + #define DEF_TEXT_FONT "Mincho:Courier-12" + #else #define DEF_TEXT_FONT "Courier -12" + #endif /* KANJI */ #define DEF_TEXT_HEIGHT "24" #define DEF_TEXT_HIGHLIGHT_BG NORMAL_BG #define DEF_TEXT_HIGHLIGHT BLACK *************** *** 436,442 **** --- 468,478 ---- * Defaults for canvas text: */ + #ifdef KANJI + #define DEF_CANVTEXT_FONT "Mincho:Helvetica-12" + #else #define DEF_CANVTEXT_FONT "Helvetica -12" + #endif /* KANJI */ /* * Defaults for toplevels (most of the defaults for frames also apply diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixDraw.c ./unix/tkUnixDraw.c *** ../../tk8.0.5/unix/tkUnixDraw.c Tue Sep 15 03:23:55 1998 --- ./unix/tkUnixDraw.c Fri Mar 12 00:39:20 1999 *************** *** 25,30 **** --- 25,33 ---- Window window; /* Window to filter. */ TkRegion region; /* Region into which damage is accumulated. */ int dx, dy; /* Amount by which window was shifted. */ + #if defined(TK_USE_INPUT_METHODS) && defined(XIM_IMPROVE) + Tk_Window tkwin; /* For checking IM is used or not. */ + #endif /* TK_USE_INPUT_METHODS && XIM_IMPROVE */ } ScrollInfo; /* *************** *** 75,80 **** --- 78,86 ---- info.region = damageRgn; info.dx = dx; info.dy = dy; + #if defined(TK_USE_INPUT_METHODS) && defined(XIM_IMPROVE) + info.tkwin = tkwin; + #endif /* TK_USE_INPUT_METHODS && XIM_IMPROVE */ /* * Sync the event stream so all of the expose events will be on the *************** *** 164,169 **** --- 170,184 ---- XUnionRectWithRegion(&rect, (Region) info->region, (Region) info->region); } else { + #if defined(TK_USE_INPUT_METHODS) && defined(XIM_IMPROVE) + if (eventPtr->type == KeyPress || + eventPtr->type == KeyRelease) { + TkWindow *winPtr = (TkWindow *)(info->tkwin); + if (winPtr->inputContext != NULL) { + info->done = 1; + } + } + #endif /* TK_USE_INPUT_METHODS && XIM_IMPROVE */ return TK_DEFER_EVENT; } return TK_DISCARD_EVENT; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixEvent.c ./unix/tkUnixEvent.c *** ../../tk8.0.5/unix/tkUnixEvent.c Tue Sep 15 03:23:56 1998 --- ./unix/tkUnixEvent.c Mon May 10 19:10:28 1999 *************** *** 16,21 **** --- 16,31 ---- #include "tkUnixInt.h" #include + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + #ifdef TK_USE_ON_THE_SPOT + #define DO_BEST_XIM + #else + #define DO_BETTER_XIM + #endif /* TK_ON_THE_SPOT */ + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ + /* * The following static indicates whether this module has been initialized. */ *************** *** 34,39 **** --- 44,96 ---- int flags)); static void DisplaySetupProc _ANSI_ARGS_((ClientData clientData, int flags)); + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + #ifdef TK_USE_ON_THE_SPOT + extern Bool TkpIMIsDisplayInBarrier _ANSI_ARGS_((Display *dpy)); + extern Bool TkpIMGetNonIMEventFromXQueue _ANSI_ARGS_((Display *dpy, XEvent *evPtr)); + extern Bool TkpIMIsEventFilterd _ANSI_ARGS_((XEvent *evPtr)); + #endif /* TK_USE_ON_THE_SPOT */ + #endif /* XIM_IMPROVE */ + + #ifdef DO_BEST_XIM + static void TkpIMQueueWindowEvent _ANSI_ARGS_((Display *dpy, int numFound, int forceBarrier)); + + static int debugCount = 0; + static void + TkpIMQueueWindowEvent(dpy, numFound, forceBarrier) + Display *dpy; + int numFound; + int forceBarrier; + { + XEvent event; + if (numFound <= 0) { + numFound = XEventsQueued(dpy, QueuedAfterReading); + } + + debugCount++; + if (TkpIMIsDisplayInBarrier(dpy) == True || + forceBarrier == 1) { + while (numFound > 0) { + if (TkpIMGetNonIMEventFromXQueue(dpy, &event) == True) { + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + } + numFound--; + } + } else { + while (numFound > 0) { + XNextEvent(dpy, &event); + if (XFilterEvent(&event, None) == True) { + numFound = XEventsQueued(dpy, QueuedAlready); + continue; + } + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + numFound--; + } + } + } + #endif /* DO_BEST_XIM */ + #endif /* TK_USE_INPUT_METHODS */ /* *---------------------------------------------------------------------- *************** *** 225,231 **** --- 282,290 ---- int flags; { TkDisplay *dispPtr; + #ifndef DO_BEST_XIM XEvent event; + #endif /* !DO_BEST_XIM */ int numFound; if (!(flags & TCL_WINDOW_EVENTS)) { *************** *** 241,251 **** --- 300,320 ---- * Transfer events from the X event queue to the Tk event queue. */ + #ifdef DO_BEST_XIM + TkpIMQueueWindowEvent(dispPtr->display, numFound, 0); + #else while (numFound > 0) { XNextEvent(dispPtr->display, &event); + #ifdef DO_BETTER_XIM + if (XFilterEvent(&event, None) == True) { + numFound = XEventsQueued(dispPtr->display, QueuedAlready); + continue; + } + #endif /* DO_BETTER_XIM */ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); numFound--; } + #endif /* DO_BEST_XIM */ } } *************** *** 273,279 **** --- 342,350 ---- { TkDisplay *dispPtr = (TkDisplay *) clientData; Display *display = dispPtr->display; + #ifndef DO_BEST_XIM XEvent event; + #endif /* !DO_BEST_XIM */ int numFound; XFlush(display); *************** *** 315,325 **** --- 386,406 ---- * Transfer events from the X event queue to the Tk event queue. */ + #ifdef DO_BEST_XIM + TkpIMQueueWindowEvent(display, numFound, 0); + #else while (numFound > 0) { XNextEvent(display, &event); + #ifdef DO_BETTER_XIM + if (XFilterEvent(&event, None) == True) { + numFound = XEventsQueued(display, QueuedAlready); + continue; + } + #endif /* DO_BETTER_XIM */ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); numFound--; } + #endif /* DO_BEST_XIM */ } /* *************** *** 481,487 **** --- 562,570 ---- Display *display; /* Display to sync. */ { int numFound = 0; + #ifndef DO_BEST_XIM XEvent event; + #endif /* !DO_BEST_XIM */ XSync(display, False); *************** *** 490,498 **** --- 573,591 ---- */ numFound = XQLength(display); + #ifdef DO_BEST_XIM + TkpIMQueueWindowEvent(display, numFound, 0); + #else while (numFound > 0) { XNextEvent(display, &event); + #ifdef DO_BETTER_XIM + if (XFilterEvent(&event, None) == True) { + numFound = XEventsQueued(display, QueuedAlready); + continue; + } + #endif /* DO_BETTER_XIM */ Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); numFound--; } + #endif /* DO_BEST_XIM */ } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixFont.c ./unix/tkUnixFont.c *** ../../tk8.0.5/unix/tkUnixFont.c Wed Nov 25 10:48:54 1998 --- ./unix/tkUnixFont.c Mon May 10 19:10:28 1999 *************** *** 21,26 **** --- 21,29 ---- #ifndef ABS #define ABS(n) (((n) < 0) ? -(n) : (n)) #endif + #ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) + #endif /* * The following structure represents Unix's implementation of a font. *************** *** 34,47 **** --- 37,62 ---- char types[256]; /* Array giving types of all characters in * the font, used when displaying control * characters. See below for definition. */ + #ifdef KANJI + unsigned char *widths; + #else int widths[256]; /* Array giving widths of all possible * characters in the font. */ + #endif /* KANJI */ int underlinePos; /* Offset from baseline to origin of * underline bar (used for simulating a native * underlined font). */ int barHeight; /* Height of underline or overstrike bar * (used for simulating a native underlined or * strikeout font). */ + #ifdef KANJI + int overstrikePos; /* Offset from baseline to origin of + * overstrike bar. */ + int overHeight; /* Height of overstrike bar. */ + #ifdef UNIXFONT_DEBUG + int isFreed; + #endif /* UNIXFONT_DEBUG */ + #endif /* KANJI */ } UnixFont; /* *************** *** 92,99 **** --- 107,213 ---- Drawable drawable, GC gc, UnixFont *fontPtr, CONST char *source, int numChars, int x, int y)); + #ifdef KANJI + static void ComputeFontWidth _ANSI_ARGS_((UnixFont *fontPtr)); + static int WStrToTextItem _ANSI_ARGS_((CONST wchar *wstr, int numWchar, UnixFont *fontPtr, + XTextItem16 *items, int numItems, XChar2b *chars, int numChars, + unsigned int *pXWidthPtr, int *numItemsPtr)); + + #endif /* KANJI */ static int GetControlCharSubst _ANSI_ARGS_((int c, char buf[4])); + #ifdef KANJI + /* + * TkpGetDPI + * return helpful information to determine which (100dpi/75dpi) + * font path's font should be used. + */ + int + TkpGetDPI(tkwin, realDPIRet) + Tk_Window tkwin; + double *realDPIRet; + { + int d100, d75; + double rDPI = ((double)(WidthOfScreen(Tk_Screen(tkwin))) / + (double)(WidthMMOfScreen(Tk_Screen(tkwin))) * 25.4); + int dpi = (int)(rDPI + .5); + + d100 = 100 - dpi; + if (d100 < 0) { + d100 = -d100; + } + d75 = 75 -dpi; + if (d75 < 0) { + d75 = -d75; + } + if (realDPIRet != NULL) { + *realDPIRet = rDPI; + } + return (d100 < d75) ? 100 : 75; + } + + + int + TkpConvertPointToPixel(tkwin, pointsize) + Tk_Window tkwin; + int pointsize; + { + double rDPI = ((double)(WidthOfScreen(Tk_Screen(tkwin))) / + (double)(WidthMMOfScreen(Tk_Screen(tkwin))) * 25.4); + double ret = (double)(pointsize) * rDPI / 72.0 + 0.5; + return (int)ret; + } + + + int + TkpConvertPixelToPoint(tkwin, pixelsize) + Tk_Window tkwin; + int pixelsize; + { + /* 72.0 : pointsize = rDPI : pixelsize */ + double rDPI = ((double)(WidthOfScreen(Tk_Screen(tkwin))) / + (double)(WidthMMOfScreen(Tk_Screen(tkwin))) * 25.4); + double ret = (double)(pixelsize) * 72.0 / rDPI + 0.5; + return (int)ret; + } + + + Tk_Uid + TkpGetFontPropertyName(tkwin, xFontPtr) + Tk_Window tkwin; + XFontStruct *xFontPtr; + { + unsigned long val; + if (XGetFontProperty(xFontPtr, XA_FONT, &val) && val != 0) { + #ifdef CHECK_XLFD + Tk_Uid aName = Tk_GetUid(Tk_GetAtomName(tkwin, val)); + Tk_Uid sName = NormalizeXLFD(aName); + if (aName == sName) { + return aName; + } else { + return sName; + } + #else + return Tk_GetUid(Tk_GetAtomName(tkwin, val)); + #endif /* CHECK_XLFD */ + } else { + /* + * Find the name from Cache struct. + */ + return TkpFindFontnameFromFontStruct(tkwin, xFontPtr); + } + } + + + Tk_Uid + TkpGetFontPropertyNameFromTkFont(tkwin, tkFont) + Tk_Window tkwin; + Tk_Font tkFont; + { + return TkpGetFontPropertyName(tkwin, ((UnixFont *)tkFont)->fontStructPtr); + } + + #endif /* KANJI */ /* *--------------------------------------------------------------------------- *************** *** 127,133 **** --- 241,251 ---- CONST char *name; /* Platform-specific font name. */ { XFontStruct *fontStructPtr; + #ifdef BUGFIX + CONST char *p; + #else char *p; + #endif /* BUGFIX */ int hasSpace, dashes, hasWild; /* *************** *** 212,224 **** --- 330,396 ---- char **nameList; XFontStruct *fontStructPtr; CONST char *fmt, *family; + #ifndef KANJI double d; + #endif /* !KANJI */ + #ifdef KANJI + char *charset; + int onceAgain = 0; + char orgTryName[256]; + int bufLen = 0; + + EXTERN Tk_Uid TkpFindOpendFontname _ANSI_ARGS_((Tk_Window tkwin, char *name)); + EXTERN void TkpAddOpendFontname _ANSI_ARGS_((Tk_Window tkwin, char *name, char *opendName)); + EXTERN void TkpDeleteOpendFontname _ANSI_ARGS_((Tk_Window tkwin, char *name)); + + fontPtr = (UnixFont *)tkFontPtr; + + if (faPtr->fontType == TK_FONT_COMPOUND) { + if (fontPtr == (UnixFont *)NULL) { + fontPtr = (UnixFont *)ckalloc(sizeof(UnixFont)); + tkFontPtr = (TkFont *)fontPtr; + memset((VOID *)fontPtr, 0, sizeof(UnixFont)); + memcpy((VOID *)&(fontPtr->font.fa), (VOID *)faPtr, + sizeof(TkFontAttributes)); + } + + fontPtr->font.asciiFontPtr = TkpGetFontFromAttributes(fontPtr->font.asciiFontPtr, tkwin, + faPtr->asciiFaPtr); + + fontPtr->font.kanjiFontPtr = TkpGetFontFromAttributes(fontPtr->font.kanjiFontPtr, tkwin, + faPtr->kanjiFaPtr); + + fontPtr->display = ((UnixFont *)(fontPtr->font.asciiFontPtr))->display; + fontPtr->fontStructPtr = ((UnixFont *)(fontPtr->font.asciiFontPtr))->fontStructPtr; + + TkpUpdateCompoundFont((TkFont *)fontPtr, faPtr); + + return (TkFont *)fontPtr; + } + + charset = faPtr->charset; + if (charset == NULL) { + charset = "iso8859"; + } + #endif /* KANJI */ family = faPtr->family; if (family == NULL) { + #ifdef KANJI + family = "fixed"; + #else family = "*"; + #endif /* KANJI */ } + + #ifdef KANJI + if (faPtr->pointsize < 0) { + pixelsize = -faPtr->pointsize; + } else { + pixelsize = TkpConvertPointToPixel(tkwin, faPtr->pointsize); + } + #else pixelsize = -faPtr->pointsize; if (pixelsize < 0) { d = -pixelsize * 25.4 / 72; *************** *** 227,233 **** d += 0.5; pixelsize = (int) d; } ! /* * Replace the standard Windows and Mac family names with the names that * X likes. --- 399,405 ---- d += 0.5; pixelsize = (int) d; } ! #endif /* KANJI */ /* * Replace the standard Windows and Mac family names with the names that * X likes. *************** *** 244,249 **** --- 416,422 ---- family = "Helvetica"; } + #ifndef KANJI /* * First try for the Q&D exact match. */ *************** *** 266,287 **** --- 439,557 ---- * Couldn't find exact match. Now fall back to other available * physical fonts. */ + #endif /* !KANJI */ + + #ifdef KANJI + /* + * First, check the font name in hash, Using best shot. + */ + orgTryName[0] = '\0'; + fontStructPtr = NULL; + if (pixelsize > 0) { + Tk_Uid opendName; + fmt = "-%.200s-%.200s-%s-%c-%s-*-%d-*-*-*-*-*-%.240s-*"; + sprintf(buf, fmt, + ((faPtr->foundry != NULL) ? faPtr->foundry : "*"), + family, + ((faPtr->weight > TK_FW_NORMAL) ? "bold" : "medium"), + ((faPtr->slant == TK_FS_ROMAN) ? 'r' : + (faPtr->slant == TK_FS_ITALIC) ? 'i' : 'o'), + ((faPtr->setwidth == TK_SW_NORMAL) ? "normal" : "*"), + pixelsize, + charset); + + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "debugFont: search '%s' (in cache) ... ", buf); + #endif /* UNIXFONT_DEBUG */ + opendName = TkpFindOpendFontname(tkwin, buf); + if (opendName != NULL) { + fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), opendName); + if (fontStructPtr != NULL) { + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "found.\n"); + #endif /* UNIXFONT_DEBUG */ + goto end; + } else { + /* + * ... Maybe X font search path was changed. + */ + TkpDeleteOpendFontname(tkwin, buf); + } + } + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "not found.\n"); + #endif /* UNIXFONT_DEBUG */ + bufLen = strlen(buf); + memcpy(orgTryName, buf, (unsigned int)bufLen); + orgTryName[bufLen] = 0; + } + /* + * OK, let's grooooove. + */ + fmt = "-%.200s-%.200s-%s-%c-%s-*-*-*-*-*-*-*-%.240s-*"; + sprintf(buf, fmt, + ((faPtr->foundry != NULL) ? faPtr->foundry : "*"), + family, + ((faPtr->weight > TK_FW_NORMAL) ? "bold" : "medium"), + ((faPtr->slant == TK_FS_ROMAN) ? 'r' : + (faPtr->slant == TK_FS_ITALIC) ? 'i' : 'o'), + ((faPtr->setwidth == TK_SW_NORMAL) ? "normal" : "*"), + charset); + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "debugFont: search '%s' (in X font list)\n", buf); + #endif /* UNIXFONT_DEBUG */ + oneMoreTry: + #else fmt = "-*-%.240s-*-*-*-*-*-*-*-*-*-*-*-*"; sprintf(buf, fmt, family); + #endif /* KANJI */ nameList = XListFonts(Tk_Display(tkwin), buf, 10000, &numNames); if (numNames == 0) { + #ifdef KANJI + if (onceAgain == 0) { + fmt = "-*-%.240s-*-*-*--*-*-*-*-*-*-%.240s-*"; + sprintf(buf, fmt, family, charset); + onceAgain = 1; + goto oneMoreTry; + } else if (onceAgain == 1) { + fmt = "-*-%.240s-*-*-*--*-*-*-*-*-*-*-*"; + sprintf(buf, fmt, family); + onceAgain = 2; + goto oneMoreTry; + } else { + fmt = "-*-%.240s-*-*-*--*-*-*-*-*-*-%.240s-*"; + sprintf(buf, fmt, "fixed", charset); + } + #else /* * Try getting some system font. */ sprintf(buf, fmt, "fixed"); + #endif /* KANJI */ nameList = XListFonts(Tk_Display(tkwin), buf, 10000, &numNames); if (numNames == 0) { getsystem: + #ifdef KANJI + if (strcasecmp(charset, "jisx0208.1983") == 0) { + fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), "k14"); + memcpy(buf, "k14", 3); + buf[3] = 0; + } else { + fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), "fixed"); + memcpy(buf, "fixed", 5); + buf[5] = 0; + } + #else fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), "fixed"); + #endif /* KANJI */ if (fontStructPtr == NULL) { fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), "*"); + #ifdef KANJI + buf[0] = '*'; + buf[1] = '\0'; + #endif /* KANJI */ if (fontStructPtr == NULL) { panic("TkpGetFontFromAttributes: cannot get any font"); } *************** *** 303,330 **** for (i = 0; i < numNames; i++) { score = 0; scaleable = 0; if (TkParseXLFD(nameList[i], &xa) != TCL_OK) { continue; } xaPixelsize = -xa.fa.pointsize; ! /* * Since most people used to use -adobe-* in their XLFDs, * preserve the preference for "adobe" foundry. Otherwise * some applications looks may change slightly if another foundry * is chosen. */ ! if (strcasecmp(xa.foundry, "adobe") != 0) { score += 3000; } if (xa.fa.pointsize == 0) { /* * A scaleable font is almost always acceptable, but the * corresponding bitmapped font would be better. */ ! score += 10; scaleable = 1; } else { /* --- 573,672 ---- for (i = 0; i < numNames; i++) { score = 0; scaleable = 0; + #ifdef KANJI + memset((VOID *)&xa, 0, sizeof(TkXLFDAttributes)); + TkInitFontAttributes(&(xa.fa)); + #endif /* KANJI */ if (TkParseXLFD(nameList[i], &xa) != TCL_OK) { continue; } + #ifdef KANJI + if (xa.fa.pointsize > 0) { + xaPixelsize = TkpConvertPointToPixel(tkwin, xa.fa.pointsize); + } else { + xaPixelsize = -xa.fa.pointsize; + } + + /* + * OK, we use -misc-*, -jis-* as well as -adobe-*. + */ + if (xa.charset != TK_CS_KANJI) { + if (strcasecmp(xa.foundry, "adobe") != 0) { + score += 3000; + } + } + #else xaPixelsize = -xa.fa.pointsize; ! /* * Since most people used to use -adobe-* in their XLFDs, * preserve the preference for "adobe" foundry. Otherwise * some applications looks may change slightly if another foundry * is chosen. */ ! if (strcasecmp(xa.foundry, "adobe") != 0) { score += 3000; } + #endif /* KANJI */ + #ifdef KANJI + if (faPtr->foundry != NULL) { + if (strcasecmp(xa.foundry, faPtr->foundry) != 0) { + score += 50000; + /* + * further more, if charset != TK_CS_NORMAL, make this BAD. + */ + if (xa.charset != TK_CS_NORMAL) { + score += 15000; + } + } + } + if (*family != '*') { + if (strcasecmp(xa.fa.family, family) != 0) { + score += 50000; + /* + * further more, if charset != TK_CS_NORMAL, make this BAD. + */ + if (xa.charset != TK_CS_NORMAL) { + score += 15000; + } + } + if (faPtr->foundry == NULL && xa.charset == TK_CS_KANJI) { + if (strcasecmp(family, "fixed") == 0) { + if (strcasecmp(xa.foundry, "jis") != 0 && + strcasecmp(xa.foundry, "misc") != 0) { + /* + * foundry is not specified, family is "fixed". + * In such a case, we preffer "jis" or "misc" foundry. + */ + score += 10000; + } + } + } + } + if (*charset == '*') { + if (xa.charset != TK_CS_NORMAL) { + score += 15000; + } + } + + #endif /* KANJI */ if (xa.fa.pointsize == 0) { /* * A scaleable font is almost always acceptable, but the * corresponding bitmapped font would be better. */ ! #ifdef KANJI ! /* ! * eg. ! * -adobe-courier-medium-r-normal--0-0-75-75-m-0-iso8859-1 ! * -adobe-courier-medium-r-normal--12-120-75-75-m-70-iso8859-1 ! * for pixel size 13, I preffer bitmap. ! */ ! score += 150; ! #else score += 10; + #endif /* KANJI */ scaleable = 1; } else { /* *************** *** 386,391 **** --- 728,740 ---- } } + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "debugScale: p = %d, scale %d '%s': bitmap %d '%s'\n", + pixelsize, + bestScaleableScore, nameList[bestScaleableIdx], + bestScore, nameList[bestIdx]); + #endif /* UNIXFONT_DEBUG */ + /* * Now we know which is the closest matching scaleable font and the * closest matching bitmapped font. If the scaleable font was a *************** *** 396,408 **** --- 745,778 ---- fontStructPtr = NULL; if (bestScaleableScore < bestScore) { + #ifdef KANJI + char *str; + int len; + #else char *str, *rest; + #endif /* KANJI */ /* * Fill in the desired pointsize info for this font. */ tryscale: + #ifdef KANJI + /* use XLFD field as possible as I can, means use all field + * except the pixelsize. */ + str = nameList[bestScaleableIdx]; + for (i = 0; i < XLFD_PIXEL_SIZE; i++) { + str = strchr(str + 1, '-'); + } + str++; + len = str - nameList[bestScaleableIdx]; + memcpy(buf, nameList[bestScaleableIdx], (unsigned int)len); + sprintf(buf + len, "%d-0", pixelsize); + len = strlen(buf); + str = strchr(str + 1, '-'); /* pass pixel. */ + str = strchr(str + 1, '-'); /* pass point. */ + sprintf(buf + len, "%s", str); + #else str = nameList[bestScaleableIdx]; for (i = 0; i < XLFD_PIXEL_SIZE - 1; i++) { str = strchr(str + 1, '-'); *************** *** 415,420 **** --- 785,794 ---- sprintf(buf, "%.240s-*-%d-*-*-*-*-*%s", nameList[bestScaleableIdx], pixelsize, rest); *str = '-'; + #endif /* KANJI */ + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "debugScale: open '%s' idx %d\n", buf, bestScaleableIdx + 1); + #endif /* UNIXFONT_DEBUG */ fontStructPtr = XLoadQueryFont(Tk_Display(tkwin), buf); bestScaleableScore = INT_MAX; } *************** *** 441,446 **** --- 815,838 ---- fontPtr = AllocFont(tkFontPtr, tkwin, fontStructPtr, buf); fontPtr->font.fa.underline = faPtr->underline; fontPtr->font.fa.overstrike = faPtr->overstrike; + #ifdef KANJI + fontPtr->font.fa.pointAdjust = faPtr->pointAdjust; + if (faPtr->pointsize < 0) { + /* user specified pixelsize ?? */ + fontPtr->font.fa.pointsize = faPtr->pointsize; + } + if (faPtr->foundry == NULL) { + fontPtr->font.fa.foundry = NULL; + } + + /* Create a hash entry for font name queryed at the top of this routine. */ + if (orgTryName[0] != '\0') { + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "debugFont: create '%s' -> '%s'\n", orgTryName, buf); + #endif /* UNIXFONT_DEBUG */ + TkpAddOpendFontname(tkwin, orgTryName, buf); + } + #endif /* KANJI */ return (TkFont *) fontPtr; } *************** *** 473,479 **** --- 865,888 ---- fontPtr = (UnixFont *) tkFontPtr; + #ifdef KANJI + if (Tk_FontType(tkFontPtr) == TK_FONT_COMPOUND) { + if (fontPtr->font.asciiFontPtr != NULL) { + TkpDeleteFont((TkFont *)fontPtr->font.asciiFontPtr); + } + if (fontPtr->font.kanjiFontPtr != NULL) { + TkpDeleteFont((TkFont *)fontPtr->font.kanjiFontPtr); + } + } else { + XFreeFont(fontPtr->display, fontPtr->fontStructPtr); + if (fontPtr->widths != NULL) ckfree(fontPtr->widths); + } + #ifdef UNIXFONT_DEBUG + fontPtr->isFreed = 1; + #endif /* UNIXFONT_DEBUG */ + #else XFreeFont(fontPtr->display, fontPtr->fontStructPtr); + #endif /* KANJI */ ckfree((char *) fontPtr); } *************** *** 501,507 **** --- 910,920 ---- Tk_Window tkwin; { int i, new, numNames; + #ifdef KANJI + char *family, *end; + #else char *family, *end, *p; + #endif /* KANJI */ Tcl_HashTable familyTable; Tcl_HashEntry *hPtr; Tcl_HashSearch search; *************** *** 524,535 **** --- 937,953 ---- continue; } *end = '\0'; + #ifdef KANJI + Tcl_CreateHashEntry(&familyTable, Tk_GetUid(family), &new); + *end = '-'; + #else for (p = family; *p != '\0'; p++) { if (isupper(UCHAR(*p))) { *p = tolower(UCHAR(*p)); } } Tcl_CreateHashEntry(&familyTable, family, &new); + #endif /* KANJI */ } hPtr = Tcl_FirstHashEntry(&familyTable, &search); *************** *** 596,601 **** --- 1014,1024 ---- int c, sawNonSpace; fontPtr = (UnixFont *) tkfont; + #ifdef KANJI + if (Tk_FontType(tkfont) == TK_FONT_COMPOUND) { + fontPtr = (UnixFont *)fontPtr->font.asciiFontPtr; + } + #endif /* KANJI */ if (numChars == 0) { *lengthPtr = 0; *************** *** 714,719 **** --- 1137,1147 ---- char buf[4]; fontPtr = (UnixFont *) tkfont; + #ifdef KANJI + if (Tk_FontType(tkfont) == TK_FONT_COMPOUND) { + fontPtr = (UnixFont *)fontPtr->font.asciiFontPtr; + } + #endif /* KANJI */ p = source; for (i = 0; i < numChars; i++) { *************** *** 780,791 **** --- 1208,1869 ---- (unsigned) fontPtr->barHeight); } if (fontPtr->font.fa.overstrike != 0) { + #ifdef KANJI + y -= fontPtr->overstrikePos; + #else y -= fontPtr->font.fm.descent + (fontPtr->font.fm.ascent) / 10; + #endif /* KANJI */ XFillRectangle(display, drawable, gc, x, y, (unsigned) XTextWidth(fontPtr->fontStructPtr, source, numChars), + #ifdef KANJI + (unsigned) fontPtr->overHeight); + #else (unsigned) fontPtr->barHeight); + #endif /* KANJI */ } } + #ifdef KANJI + + /* + *--------------------------------------------------------------------------- + * + * ComputeFontWidth + * + * Compute the font width. + * + * Results: + * Width of each symbol is stored in fontPtr->widths. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + static void + ComputeFontWidth(fontPtr) + UnixFont *fontPtr; + { + XFontStruct *fontStructPtr = fontPtr->fontStructPtr; + int i, width, firstChar, lastChar, n, replaceOK; + char *p; + char buf[4]; + switch (Tk_FontType(fontPtr)) { + case TK_FONT_GENERIC: { + fontPtr->font.asciiFontPtr = (TkFont *)fontPtr; + fontPtr->font.kanjiFontPtr = NULL; + fontPtr->widths = (unsigned char *)ckalloc(256); + memset((VOID *)(fontPtr->types), SKIP, 256); + memset((VOID *)(fontPtr->widths), 0, 256); + + firstChar = fontStructPtr->min_char_or_byte2; + lastChar = fontStructPtr->max_char_or_byte2; + for (i = 0; i < 256; i++) { + if ((i == 0177) || (i < firstChar) || (i > lastChar)) { + fontPtr->types[i] = REPLACE; + } else { + fontPtr->types[i] = NORMAL; + } + } + + /* + * Compute the widths for all the normal characters. Any other + * characters are given an initial width of 0. Also, this determines + * if this is a fixed or variable width font, by comparing the widths + * of all the normal characters. + */ + + width = 0; + for (i = 0; i < 256; i++) { + if (fontPtr->types[i] != NORMAL) { + n = 0; + } else if (fontStructPtr->per_char == NULL) { + n = fontStructPtr->max_bounds.width; + } else { + n = fontStructPtr->per_char[i - firstChar].width; + } + fontPtr->widths[i] = n; + if (n != 0) { + if (width == 0) { + width = n; + } else if (width != n) { + fontPtr->font.fm.fixed = 0; + } + } + } + + /* + * Compute the widths of the characters that should be replaced with + * control character expansions. If the appropriate chars are not + * available in this font, then control character expansions will not + * be used; control chars will be invisible & zero-width. + */ + + replaceOK = 1; + for (p = hexChars; *p != '\0'; p++) { + if ((UCHAR(*p) < firstChar) || (UCHAR(*p) > lastChar)) { + replaceOK = 0; + break; + } + } + for (i = 0; i < 256; i++) { + if (fontPtr->types[i] == REPLACE) { + if (replaceOK) { + n = GetControlCharSubst(i, buf); + for (; --n >= 0;) { + fontPtr->widths[i] += fontPtr->widths[UCHAR(buf[n])]; + } + } else { + fontPtr->types[i] = SKIP; + } + } + } + break; + } + + case TK_FONT_2BYTES: { + #define TWO_BYTES_RANGE 65536 + #define KANJI_RANGE 32896 /* 128*256+128 */ + int min_byte1 = fontStructPtr->min_byte1; + int max_byte1 = fontStructPtr->max_byte1; + int min_byte2 = fontStructPtr->min_char_or_byte2; + int max_byte2 = fontStructPtr->max_char_or_byte2; + int rownum = max_byte2 - min_byte2 + 1; + int i, j, n; + + fontPtr->font.asciiFontPtr = NULL; + fontPtr->font.kanjiFontPtr = (TkFont *)fontPtr; + fontPtr->widths = (unsigned char *)ckalloc(TWO_BYTES_RANGE); + /* + * fontPtr->types is not used if kanji font. + * just fill SKIP. + */ + memset((VOID *)(fontPtr->types), SKIP, 256); + memset((VOID *)(fontPtr->widths), 0, TWO_BYTES_RANGE); + + for (i = min_byte1; i <= max_byte1; i++) { + for (j = min_byte2; j <= max_byte2; j++) { + n = (i<<8) + j; + n &= 0x7f7f; /* for EUC encoding kanji font (ex DEC's) */ + if (n < 0 || n > KANJI_RANGE) continue; + if (fontStructPtr->per_char == NULL) { + fontPtr->widths[n] = fontStructPtr->min_bounds.width; + } else { + fontPtr->widths[n] = + fontStructPtr->per_char[(i-min_byte1)*rownum+(j-min_byte2)].width; + } + } + } + break; + } + } + } + + /* + *--------------------------------------------------------------------------- + * + * TkpGetFailsafeFont + * + * Get the failsafe font. + * + * Results: + * Return the failsafe font. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + void + TkpGetFailsafeFont(tkfont, asciiFPtr, kanjiFPtr) + Tk_Font tkfont; + Tk_Font *asciiFPtr; + Tk_Font *kanjiFPtr; + { + UnixFont *defaultF = NULL; + int tkFontType = Tk_FontType(tkfont); + + if (tkFontType == TK_FONT_COMPOUND) { + /* Sounds Goooood. */ + *asciiFPtr = (Tk_Font)(((TkFont *)tkfont)->asciiFontPtr); + *kanjiFPtr = (Tk_Font)(((TkFont *)tkfont)->kanjiFontPtr); + return; + } + + *asciiFPtr = NULL; + *kanjiFPtr = NULL; + defaultF = (UnixFont *)TkpGetDefaultFontByDisplay(((UnixFont *)tkfont)->display); + if (defaultF != NULL) { + int defFontType = Tk_FontType((Tk_Font)defaultF); + switch(tkFontType) { + case TK_FONT_GENERIC: { + *asciiFPtr = (Tk_Font)(((TkFont *)tkfont)->asciiFontPtr); + if (defFontType == TK_FONT_COMPOUND || defFontType == TK_FONT_2BYTES) { + /* Well, try to use kanji font in default font. */ + *kanjiFPtr = (Tk_Font)(((TkFont *)defaultF)->kanjiFontPtr); + } + break; + } + case TK_FONT_2BYTES: { + *kanjiFPtr = (Tk_Font)(((TkFont *)tkfont)->kanjiFontPtr); + if (defFontType == TK_FONT_COMPOUND || defFontType == TK_FONT_GENERIC) { + *asciiFPtr = (Tk_Font)(((TkFont *)defaultF)->asciiFontPtr); + } + break; + } + } + } else { + switch(tkFontType) { + case TK_FONT_GENERIC: { + *asciiFPtr = (Tk_Font)(((TkFont *)tkfont)->asciiFontPtr); + break; + } + case TK_FONT_2BYTES: { + *kanjiFPtr = (Tk_Font)(((TkFont *)tkfont)->kanjiFontPtr); + break; + } + } + } + if (*asciiFPtr == NULL && *kanjiFPtr == NULL) { + panic("FailsafeFont: can't get ANY font."); + } + return; + } + + #ifdef UNIXFONT_DEBUG + #define FailsafeFont(TK, ASC, KNJ) \ + if (((UnixFont *)(TK))->isFreed == 1) { \ + panic("FailsafeFont: freed font reference."); \ + } \ + if (Tk_FontType(((Tk_Font)(TK))) == TK_FONT_COMPOUND) { \ + ASC = (UnixFont *)(((TkFont *)(TK))->asciiFontPtr); \ + KNJ = (UnixFont *)(((TkFont *)(TK))->kanjiFontPtr); \ + fprintf(stderr, "debugFailF: tkfont(compd) 0x%08x, ascii 0x%08x kanji 0x%08x\n", \ + (TK), (ASC), (KNJ)); \ + } else { \ + TkpGetFailsafeFont(((Tk_Font)(TK)), (Tk_Font *)(&(ASC)), (Tk_Font *)(&(KNJ))); \ + fprintf(stderr, "debugFailF: tkfont(%s) 0x%08x, ascii 0x%08x kanji 0x%08x\n", \ + (Tk_FontType(((Tk_Font)(TK))) == TK_FONT_GENERIC) ? "ascii" : "kanji", \ + (TK), (ASC), (KNJ)); \ + } \ + fprintf(stderr, "\t\t'%s', '%s'\n", \ + ((ASC) != NULL) ? ((Tk_FontCharset((Tk_Font)(ASC)) != NULL) ? Tk_FontCharset((Tk_Font)(ASC)) : "") : "", \ + ((KNJ) != NULL) ? ((Tk_FontCharset((Tk_Font)(KNJ)) != NULL) ? Tk_FontCharset((Tk_Font)(KNJ)) : "") : ""); + #else + #define FailsafeFont(TK, ASC, KNJ) \ + if (Tk_FontType(((Tk_Font)(TK))) == TK_FONT_COMPOUND) { \ + ASC = (UnixFont *)(((TkFont *)(TK))->asciiFontPtr); \ + KNJ = (UnixFont *)(((TkFont *)(TK))->kanjiFontPtr); \ + } else { \ + TkpGetFailsafeFont(((Tk_Font)(TK)), (Tk_Font *)(&(ASC)), (Tk_Font *)(&(KNJ))); \ + } + #endif /* UNIXFONT_DEBUG */ + + /* + *--------------------------------------------------------------------------- + * + * Tk_MeasureWChars -- + * + * Determine the number of characters from the string that will fit + * in the given horizontal span. The measurement is done under the + * assumption that Tk_DrawWChars() will be used to actually display + * the characters. + * + * Results: + * The return value is the number of characters from source that + * fit into the span that extends from 0 to maxLength. *lengthPtr is + * filled with the x-coordinate of the right edge of the last + * character that did fit. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + + int + Tk_MeasureWChars(tkfont, source, numChars, maxLength, flags, lengthPtr) + Tk_Font tkfont; /* Font in which characters will be drawn. */ + CONST wchar *source; /* Characters to be displayed. Need not be + * '\0' terminated. */ + int numChars; /* Maximum number of characters to consider + * from source string. */ + int maxLength; /* If > 0, maxLength specifies the longest + * permissible line length; don't consider any + * character that would cross this + * x-position. If <= 0, then line length is + * unbounded and the flags argument is + * ignored. */ + int flags; /* Various flag bits OR-ed together: + * TK_PARTIAL_OK means include the last char + * which only partially fit on this line. + * TK_WHOLE_WORDS means stop on a word + * boundary, if possible. + * TK_AT_LEAST_ONE means return at least one + * character even if no characters fit. */ + int *lengthPtr; /* Filled with x-location just after the + * terminating character. */ + { + #define DO_KINSOKU_ALL + UnixFont *kanjiF = NULL; + UnixFont *asciiF = NULL; + CONST wchar *p; /* Current character. */ + CONST wchar *term; /* Pointer to most recent character that + * may legally be a terminating character. */ + int termX; /* X-position just after term. */ + int curX; /* X-position corresponding to p. */ + int newX; /* X-position corresponding to p+1. */ + int c, sawNonSpace; + + if (numChars == 0) { + *lengthPtr = 0; + return 0; + } + + if (maxLength <= 0) { + maxLength = INT_MAX; + } + + newX = curX = termX = 0; + p = term = source; + c = UCHAR(*p); + sawNonSpace = !ISWSPACE(c); + + FailsafeFont(tkfont, asciiF, kanjiF); + + /* + * Scan the input string one character at a time, calculating width. + */ + + for (;;) { + c = *p & 0x8080; + switch(c) { + case G0MASK: + case G2MASK: + case G3MASK: { + if (asciiF != NULL) { + c = *p & 0xff; + newX += asciiF->widths[c]; + } else if (kanjiF != NULL) { + c = *p & 0x7f7f; + newX += kanjiF->widths[c]; + } + break; + } + case G1MASK: { + if (kanjiF != NULL) { + c = *p & 0x7f7f; + newX += kanjiF->widths[c]; + } else if (asciiF != NULL) { + c = *p & 0xff; + newX += asciiF->widths[c]; + } + break; + } + } + + if (newX > maxLength) { + break; + } + curX = newX; + numChars--; + p++; + + if (numChars == 0) { + term = p; + termX = curX; + break; + } + + c = UCHAR(*p); + #ifdef DO_KINSOKU_ALL + if (ISWSPACE(c)) { + if (sawNonSpace) { + term = p; + termX = curX; + sawNonSpace = 0; + } + } else { + sawNonSpace = 1; + if (TkpIsBreakablePoint(*(p - 1), *p) && !ISWSPACE(UCHAR(*(p - 1)))) { + term = (wchar *)p; + termX = curX; + } + } + #else + if (ISWSPACE(c)) { + if (sawNonSpace) { + term = p; + termX = curX; + sawNonSpace = 0; + } + } else { + sawNonSpace = 1; + } + #endif + } + + /* + * P points to the first character that doesn't fit in the desired + * span. Use the flags to figure out what to return. + */ + + if ((flags & TK_PARTIAL_OK) && (numChars > 0) && (curX < maxLength)) { + /* + * Include the first character that didn't quite fit in the desired + * span. The width returned will include the width of that extra + * character. + */ + + numChars--; + curX = newX; + p++; + } + if ((flags & TK_AT_LEAST_ONE) && (term == source) && (numChars > 0)) { + term = p; + termX = curX; + if (term == source) { + term++; + termX = newX; + } + } else if ((numChars == 0) || !(flags & TK_WHOLE_WORDS)) { + term = p; + termX = curX; + } + + *lengthPtr = termX; + return term - source; + } + + + static int + WStrToTextItem(wstr, numWchar, fontPtr, items, numItems, + chars, numChars, pXWidthPtr, numItemsPtr) + CONST wchar *wstr; + int numWchar; + UnixFont *fontPtr; + XTextItem16 *items; + int numItems; + XChar2b *chars; + int numChars; + unsigned int *pXWidthPtr; + int *numItemsPtr; + { + int i = 0; + UnixFont *kanjiF = NULL; + UnixFont *asciiF = NULL; + int curX = 0; + int b; + XTextItem16 *iPtr = items; + XChar2b *cPtr = chars; + XChar2b *cEndPtr = chars + numChars - 1; + + /* + * Initialize the first item's members except font. + */ + iPtr->chars = cPtr; + iPtr->delta = 0; + iPtr->nchars = 0; + + FailsafeFont(fontPtr, asciiF, kanjiF); + + #define DoLoop(X) for (X = 0; (X < numWchar) && (cPtr <= cEndPtr); X++) + + #define changeFont(toFont) \ + if (iPtr < iEndPtr) { \ + iPtr++; \ + } else { \ + goto done; \ + } \ + iPtr->delta = 0; \ + iPtr->nchars = 0; \ + iPtr->chars = cPtr; \ + lastFont = toFont; \ + iPtr->font = lastFont->font.fid; + + #define expandControls(c) \ + char buf[4]; \ + int numBuf = GetControlCharSubst(c, buf); \ + if ((cPtr + numBuf) < cEndPtr) { \ + int j; \ + for (j = 0; j < numBuf; j++) { \ + cPtr->byte1 = 0; \ + cPtr->byte2 = buf[j]; \ + cPtr++; \ + } \ + iPtr->nchars += numBuf; \ + } else { \ + i--; \ + goto done; \ + } + + if (asciiF != NULL && kanjiF != NULL) { + XTextItem16 *iEndPtr = items + numItems - 1; + UnixFont *lastFont; + if ((wstr[0] & 0x8080) == G1MASK) { + lastFont = kanjiF; + } else { + lastFont = asciiF; + } + iPtr->font = lastFont->font.fid; + + DoLoop(i) { + if ((wstr[i] & 0x8080) != G1MASK) { + if (lastFont == kanjiF) { + changeFont(asciiF); + } + b = wstr[i] & 0xff; + if (lastFont->types[b] == REPLACE) { + expandControls(b); + } else { + cPtr->byte1 = 0; + cPtr->byte2 = b; + cPtr++; + iPtr->nchars++; + } + } else { + if (lastFont == asciiF) { + changeFont(kanjiF); + } + b = wstr[i] & 0x7f7f; + cPtr->byte1 = b >> 8; + cPtr->byte2 = b & 0x7f; + cPtr++; + iPtr->nchars++; + } + curX += lastFont->widths[b]; + } + } else if (asciiF != NULL && kanjiF == NULL) { + iPtr->font = asciiF->font.fid; + DoLoop(i) { + b = wstr[i] & 0xff; + if (asciiF->types[b] == REPLACE) { + expandControls(b); + } else { + cPtr->byte1 = 0; + cPtr->byte2 = b; + cPtr++; + iPtr->nchars++; + } + curX += asciiF->widths[b]; + } + } else if (asciiF == NULL && kanjiF != NULL) { + iPtr->font = kanjiF->font.fid; + DoLoop(i) { + b = wstr[i] & 0x7f7f; + cPtr->byte1 = b >> 8; + cPtr->byte2 = b & 0x7f; + cPtr++; + iPtr->nchars++; + curX += kanjiF->widths[b]; + } + } else { + panic("WStrToTextItem: No valid font!"); + } + + done: + *pXWidthPtr = curX; + *numItemsPtr = iPtr - items + 1; + if (*numItemsPtr > numItems) *numItemsPtr = numItems; + return i; + #undef DoLoop + #undef changeFont + #undef expandControls + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_DrawWChars -- + * + * Draw a string of characters on the screen. Tk_DrawWChars() + * expands control characters that occur in the string to \X or + * \xXX sequences. DrawWChars() just draws the strings. + * + * Results: + * None. + * + * Side effects: + * Information gets drawn on the screen. + * + *--------------------------------------------------------------------------- + */ + + void + Tk_DrawWChars(display, drawable, gc, tkfont, source, numChars, x, y) + Display *display; /* Display on which to draw. */ + Drawable drawable; /* Window or pixmap in which to draw. */ + GC gc; /* Graphics context for drawing characters. */ + Tk_Font tkfont; /* Font in which characters will be drawn; + * must be the same as font used in GC. */ + CONST wchar *source; /* Characters to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are + * not stripped out, they will be displayed as + * regular printing characters. */ + int numChars; /* Number of characters in string. */ + int x, y; /* Coordinates at which to place origin of + * string when drawing. */ + { + int nItem; + int xPos; + int nAdv; + int curX = x; + + #define MAX_ITEMS 1024 + #define MAX_CHARS 1024 + XTextItem16 items[MAX_ITEMS]; + XChar2b chars[MAX_CHARS]; + + do { + nAdv = WStrToTextItem(source, numChars, (UnixFont *)tkfont, items, MAX_ITEMS, + chars, MAX_CHARS, &xPos, &nItem); + #ifdef UNIXFONT_DEBUG + { + int i; + int j; + + fprintf(stderr, "CharDebug: source 0x%x, incr = %d, remain = %d, item = %d chars 0x%08x\n", + source, nAdv, numChars, nItem, chars); + + for (i = 0; i < nItem; i++) { + for (j = 0; j < items[i].nchars; j++) { + fprintf(stderr, "debug: item [%.5d, %.5d] 'x%02x%02x', 0x%08x\n", + i, j, items[i].chars[j].byte1, + items[i].chars[j].byte2, + &(items[i].chars[j])); + } + } + } + #endif /* UNIXFONT_DEBUG */ + if (nItem > 0) { + XDrawText16(display, drawable, gc, curX, y, items, nItem); + } else { + break; + } + source += nAdv; + curX += xPos; + numChars -= nAdv; + } while (numChars > 0); + xPos = curX - x; + + if (((UnixFont *)tkfont)->font.fa.underline != 0) { + XFillRectangle(display, drawable, gc, x, y + ((UnixFont *)tkfont)->underlinePos, + (unsigned)xPos, + (unsigned)((UnixFont *)tkfont)->barHeight); + } + if (((UnixFont *)tkfont)->font.fa.overstrike != 0) { + y -= ((UnixFont *)tkfont)->overstrikePos; + XFillRectangle(display, drawable, gc, x, y, + (unsigned)xPos, + (unsigned)((UnixFont *)tkfont)->overHeight); + } + return; + } + #endif /* KANJI */ /* *--------------------------------------------------------------------------- *************** *** 824,840 **** { UnixFont *fontPtr; unsigned long value; int i, width, firstChar, lastChar, n, replaceOK; char *name, *p; char buf[4]; TkXLFDAttributes xa; double d; ! if (tkFontPtr != NULL) { fontPtr = (UnixFont *) tkFontPtr; XFreeFont(fontPtr->display, fontPtr->fontStructPtr); } else { fontPtr = (UnixFont *) ckalloc(sizeof(UnixFont)); } /* --- 1902,1948 ---- { UnixFont *fontPtr; unsigned long value; + #ifdef KANJI + int isFirstAlloc = 0; + char *name; + #else int i, width, firstChar, lastChar, n, replaceOK; char *name, *p; char buf[4]; + #endif /* KANJI */ TkXLFDAttributes xa; + #ifndef KANJI double d; ! #endif /* !KANJI */ ! if (tkFontPtr != NULL) { fontPtr = (UnixFont *) tkFontPtr; + #ifdef KANJI + #ifdef UNIXFONT_DEBUG + if (fontPtr->isFreed == 1) { + panic("AllocFont: freed font reference."); + } + #endif /* UNIXFONT_DEBUG */ + if (Tk_FontType(tkFontPtr) == TK_FONT_COMPOUND) { + return (UnixFont *) tkFontPtr; + } + if (fontPtr->widths != NULL) { + ckfree(fontPtr->widths); + fontPtr->widths = NULL; + } + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "debugAllocFont: tkfont(%s) 0x%08lx is re-initialized.\n", + (Tk_FontType(tkFontPtr) == TK_FONT_GENERIC) ? "ascii" : "kanji", + fontPtr); + #endif /* UNIXFONT_DEBUG */ + #endif /* KANJI */ XFreeFont(fontPtr->display, fontPtr->fontStructPtr); } else { fontPtr = (UnixFont *) ckalloc(sizeof(UnixFont)); + #ifdef KANJI + memset((VOID *)fontPtr, 0, sizeof(UnixFont)); + isFirstAlloc = 1; + #endif /* KANJI */ } /* *************** *** 856,864 **** --- 1964,2011 ---- fontPtr->font.fa.family = Tk_GetUid(fontName); } else { ok: + #ifdef KANJI + if (isFirstAlloc == 1) { + memcpy((VOID *)&(fontPtr->font.fa), (VOID *)&(xa.fa), + sizeof(TkFontAttributes)); + } else { + /* Mayhaps we have configured value. */ + int overstrike = fontPtr->font.fa.overstrike; + int underline = fontPtr->font.fa.underline; + double pointAdjust = fontPtr->font.fa.pointAdjust; + memcpy((VOID *)&(fontPtr->font.fa), (VOID *)&(xa.fa), + sizeof(TkFontAttributes)); + fontPtr->font.fa.overstrike = overstrike; + fontPtr->font.fa.underline = underline; + fontPtr->font.fa.pointAdjust = pointAdjust; + } + #else fontPtr->font.fa = xa.fa; + #endif /* KANJI */ + } + + #ifdef KANJI + /* If the Tk_FontType(fontPtr) == TK_FONT_OTHER, must need to + * check whether the font is for 2 byte charset or not. To check + * this, In X window, use the informations in XFontStruct. */ + #ifdef UNIXFONT_DEBUG + fprintf(stderr, "\nmin_char_or_byte2 = %d\n", fontStructPtr->min_char_or_byte2); + fprintf(stderr, "max_char_or_byte2 = %d\n", fontStructPtr->max_char_or_byte2); + fprintf(stderr, "min_byte1 = %d\n", fontStructPtr->min_byte1); + fprintf(stderr, "max_byte1 = %d\n", fontStructPtr->max_byte1); + #endif /* UNIXFONT_DEBUG */ + if (Tk_FontType(fontPtr) != TK_FONT_GENERIC && + Tk_FontType(fontPtr) != TK_FONT_2BYTES && + Tk_FontType(fontPtr) != TK_FONT_COMPOUND) { + if (fontStructPtr->min_byte1 == 0 && fontStructPtr->max_byte1 == 0) { + Tk_FontType(fontPtr) = TK_FONT_GENERIC; + } else { + Tk_FontType(fontPtr) = TK_FONT_2BYTES; + } } + #endif /* KANJI */ + #ifndef KANJI if (fontPtr->font.fa.pointsize < 0) { d = -fontPtr->font.fa.pointsize * 72 / 25.4; d *= WidthMMOfScreen(Tk_Screen(tkwin)); *************** *** 866,878 **** d += 0.5; fontPtr->font.fa.pointsize = (int) d; } ! fontPtr->font.fm.ascent = fontStructPtr->ascent; fontPtr->font.fm.descent = fontStructPtr->descent; fontPtr->font.fm.maxWidth = fontStructPtr->max_bounds.width; fontPtr->font.fm.fixed = 1; fontPtr->display = Tk_Display(tkwin); fontPtr->fontStructPtr = fontStructPtr; /* * Classify the characters. --- 2013,2029 ---- d += 0.5; fontPtr->font.fa.pointsize = (int) d; } ! #endif /* !KANJI */ ! fontPtr->font.fm.ascent = fontStructPtr->ascent; fontPtr->font.fm.descent = fontStructPtr->descent; fontPtr->font.fm.maxWidth = fontStructPtr->max_bounds.width; fontPtr->font.fm.fixed = 1; fontPtr->display = Tk_Display(tkwin); fontPtr->fontStructPtr = fontStructPtr; + #ifdef KANJI + ComputeFontWidth(fontPtr); + #else /* * Classify the characters. *************** *** 940,945 **** --- 2091,2097 ---- } } } + #endif /* KANJI */ if (XGetFontProperty(fontStructPtr, XA_UNDERLINE_POSITION, &value)) { fontPtr->underlinePos = value; *************** *** 948,954 **** * If the XA_UNDERLINE_POSITION property does not exist, the X * manual recommends using the following value: */ ! fontPtr->underlinePos = fontStructPtr->descent / 2; } fontPtr->barHeight = 0; --- 2100,2110 ---- * If the XA_UNDERLINE_POSITION property does not exist, the X * manual recommends using the following value: */ ! #ifdef KANJI ! if (Tk_FontType(fontPtr) == TK_FONT_2BYTES) { ! fontPtr->underlinePos = fontStructPtr->descent - 1; ! } else ! #endif /* KANJI */ fontPtr->underlinePos = fontStructPtr->descent / 2; } fontPtr->barHeight = 0; *************** *** 959,964 **** --- 2115,2127 ---- fontPtr->barHeight = value; } if (fontPtr->barHeight == 0) { + #ifdef KANJI + if (Tk_FontType(fontPtr) == TK_FONT_GENERIC) { + fontPtr->barHeight = fontPtr->widths['I'] / 3; + } else { + fontPtr->barHeight = (ABS(fontPtr->font.fm.ascent) + ABS(fontPtr->font.fm.descent)) / 10; + } + #else /* * If the XA_UNDERLINE_THICKNESS property does not exist, the X * manual recommends using the width of the stem on a capital *************** *** 967,972 **** --- 2130,2136 ---- */ fontPtr->barHeight = fontPtr->widths['I'] / 3; + #endif /* KANJI */ if (fontPtr->barHeight == 0) { fontPtr->barHeight = 1; } *************** *** 984,990 **** fontPtr->barHeight = 1; } } ! return fontPtr; } --- 2148,2160 ---- fontPtr->barHeight = 1; } } ! #ifdef KANJI ! fontPtr->overstrikePos = fontStructPtr->descent / 2; ! fontPtr->overHeight = fontPtr->barHeight; ! ! fontPtr->font.underlinePos = fontPtr->underlinePos; ! fontPtr->font.underlineHeight = fontPtr->barHeight; ! #endif /* KANJI */ return fontPtr; } *************** *** 1025,1027 **** --- 2195,2295 ---- return 4; } } + + #ifdef KANJI + + void + TkpUpdateCompoundFont(tkFontPtr, faPtr) + TkFont *tkFontPtr; + CONST TkFontAttributes *faPtr; + { + UnixFont *fontPtr = (UnixFont *)tkFontPtr; + UnixFont *ascii = (UnixFont *)fontPtr->font.asciiFontPtr; + UnixFont *kanji = (UnixFont *)fontPtr->font.kanjiFontPtr; + + if (ascii == (UnixFont *)NULL) { + panic("ascii font NULL."); + } + if (kanji == NULL) { + panic("kanji font NULL."); + } + + if (ascii->font.tabWidth > kanji->font.tabWidth) { + fontPtr->font.tabWidth = ascii->font.tabWidth; + } else { + fontPtr->font.tabWidth = kanji->font.tabWidth; + } + + if (ascii->font.fm.ascent > kanji->font.fm.ascent) { + fontPtr->font.fm.ascent = ascii->font.fm.ascent; + fontPtr->overstrikePos = kanji->font.fm.ascent / 2; + } else { + fontPtr->font.fm.ascent = kanji->font.fm.ascent; + fontPtr->overstrikePos = ascii->font.fm.ascent / 2; + } + + if (ascii->font.fm.descent > kanji->font.fm.descent) { + fontPtr->font.fm.descent = ascii->font.fm.descent; + fontPtr->underlinePos = kanji->font.fm.descent; + } else { + fontPtr->font.fm.descent = kanji->font.fm.descent; + fontPtr->underlinePos = ascii->font.fm.descent; + } + fontPtr->underlinePos++; + if (fontPtr->underlinePos >= fontPtr->font.fm.descent) { + fontPtr->underlinePos = fontPtr->font.fm.descent - 1; + } + if (fontPtr->underlinePos < 1) { + fontPtr->underlinePos = 1; + } + fontPtr->barHeight = ABS(fontPtr->font.fm.descent - fontPtr->underlinePos); + fontPtr->overHeight = (fontPtr->font.fm.descent + fontPtr->font.fm.ascent) / 10; + if (fontPtr->barHeight > fontPtr->overHeight) { + fontPtr->barHeight = fontPtr->overHeight; + } + + if (ascii->font.fm.maxWidth > kanji->font.fm.maxWidth) { + fontPtr->font.fm.maxWidth = ascii->font.fm.maxWidth; + } else { + fontPtr->font.fm.maxWidth = kanji->font.fm.maxWidth; + } + + if (ascii->font.fm.fixed != 0 && kanji->font.fm.fixed != 0) { + fontPtr->font.fm.fixed = kanji->font.fm.fixed; + } + + fontPtr->font.underlinePos = fontPtr->underlinePos; + fontPtr->font.underlineHeight = fontPtr->barHeight; + + if (faPtr != NULL) { + fontPtr->font.fa.underline = faPtr->underline; + fontPtr->font.fa.overstrike = faPtr->overstrike; + fontPtr->font.fa.pointAdjust = faPtr->pointAdjust; + } + } + + /* + * tkKinput2.c needs this. + */ + + XFontStruct * + TkpGetFontStruct(tkfont) + Tk_Font tkfont; + { + return ((UnixFont *)tkfont)->fontStructPtr; + } + + XFontStruct * + TkpGetAsciiFontStruct(tkfont) + Tk_Font tkfont; + { + return ((UnixFont *)(((UnixFont *)tkfont)->font.asciiFontPtr))->fontStructPtr; + } + + XFontStruct * + TkpGetKanjiFontStruct(tkfont) + Tk_Font tkfont; + { + return ((UnixFont *)(((UnixFont *)tkfont)->font.kanjiFontPtr))->fontStructPtr; + } + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixFontCache.c ./unix/tkUnixFontCache.c *** ../../tk8.0.5/unix/tkUnixFontCache.c Thu Jan 1 09:00:00 1970 --- ./unix/tkUnixFontCache.c Fri Mar 12 00:39:22 1999 *************** *** 0 **** --- 1,1292 ---- + /* + * tkUnixFontCache.c + * + * This file contains modules to improve performance of font handling. + * + * Author: m-hirano@sra.co.jp + * + * Copyright 1998-1999 Software Research Associates, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + */ + + #ifndef lint + static char rcsid[] = "$Id: tkUnixFontCache.c,v 1.20 1999/03/11 15:39:22 m-hirano Exp $"; + #endif /* !lint */ + + #ifdef KANJI + + #define CACHE_INCORE + + #include "tclInt.h" + #include "tkPort.h" + #include "tkInt.h" + + #include "tkFont.h" + + #ifndef Xmalloc + #ifdef MALLOC_0_RETURNS_NULL + + # define Xmalloc(size) malloc(((size) == 0 ? 1 : (size))) + # define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size))) + # define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize)) + + #else + + # define Xmalloc(size) malloc((size)) + # define Xrealloc(ptr, size) realloc((ptr), (size)) + # define Xcalloc(nelem, elsize) calloc((nelem), (elsize)) + + #endif + #endif /* Xmalloc */ + + typedef struct { + Tk_Uid name; + XFontSet xFontSet; + int refCount; + Tcl_HashEntry *entry; + } TkpFontSetCache; + + typedef struct { + Tk_Uid name; + Display *dpy; + } TkpFontSetCacheKey; + + typedef struct TkpFontNameAlias { + Tcl_HashEntry *entry; + struct TkpFontNameAlias *next; + } TkpFontNameAliasRec; + + typedef struct { + Tk_Uid name; + Display *dpy; + XFontStruct *xFontPtr; + int refCount; + int maxRef; + TkpFontNameAliasRec *alias; + TkpFontNameAliasRec *aTail; + int toBeFree; + } TkpFontCache; + + typedef struct { + Tk_Uid name; + Display *dpy; + } TkpFontCacheKey; + + typedef struct { + char **nameList; + int numFonts; + Tcl_HashTable exactTable; + } TkpFontList; + + + static Tcl_HashTable xFontSetKeyTable; + static Tcl_HashTable xFontSetCacheTable; + + static Tcl_HashTable xFontKeyTable; + static Tcl_HashTable xFontCacheTable; + + static Tcl_HashTable xFontListTable; + + Tcl_HashTable xFindFontTable; + Tcl_HashTable needXFreeFontListTable; + + void + TkpFontCachePkgInit() + { + static int xFontCacheInited = 0; + + if (xFontCacheInited == 0) { + Tcl_InitHashTable(&xFindFontTable, sizeof(TkpFontCacheKey)/sizeof(int)); + Tcl_InitHashTable(&needXFreeFontListTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&xFontListTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&xFontCacheTable, sizeof(TkpFontCacheKey)/sizeof(int)); + Tcl_InitHashTable(&xFontKeyTable, TCL_ONE_WORD_KEYS); + Tcl_InitHashTable(&xFontSetCacheTable, sizeof(TkpFontSetCacheKey)/sizeof(int)); + Tcl_InitHashTable(&xFontSetKeyTable, TCL_ONE_WORD_KEYS); + xFontCacheInited = 1; + } + } + + static char regBuf[4096]; + static char * + PatternToRegexp(pat) + char *pat; + { + char *ret = regBuf; + char *start = pat; + int lastIsDoller = 0; + + if (*start != '*') { + *ret = '^'; + ret++; + } + if (start[strlen(start) - 1] != '*') { + lastIsDoller = 1; + } + while (*start != 0) { + switch (*start) { + case '*': { + *ret = '.'; + ret++; + *ret = '*'; + break; + } + case '-': { + *ret = '-'; + break; + } + default: { + if (isalpha(*start)) { + *ret = tolower(*start); + } else { + *ret = *start; + } + break; + } + } + start++; + ret++; + } + if (lastIsDoller == 1) { + *ret = '$'; + ret++; + } + *ret = 0; + return regBuf; + } + + + static int + fontComp(a, b) + char **a, **b; + { + char *s0 = *a; + char *s1 = *b; + while (*s0 && *s1 && *s0 == *s1) { + s0++; + s1++; + } + return (*s0 - *s1); + } + + + static TkpFontList * + GetFontListByDisplay(dpy) + Display *dpy; + { + TkpFontList *ret = NULL; + int num; + #ifdef USE_OWN_XLSFONT + char **list = TkUnixXListFonts(dpy, "*", 100000, &num); + #else + char **list = XListFonts(dpy, "*", 100000, &num); + #endif /* USE_OWN_XLSFONT */ + if (list != NULL && num > 0) { + char *tmp; + int i; + for (i = 0; i < num; i++) { + tmp = list[i]; + while (*tmp != 0) { + if (isalpha(*tmp)) { + *tmp = tolower(*tmp); + } + tmp++; + } + } + qsort(&(list[0]), (unsigned int)num, sizeof(char *), fontComp); + ret = (TkpFontList *)ckalloc(sizeof(TkpFontList)); + ret->nameList = list; + ret->numFonts = num; + Tcl_InitHashTable(&(ret->exactTable), TCL_STRING_KEYS); + } + return ret; + } + + + char ** + #ifdef USE_OWN_XLSFONT + #if NeedFunctionPrototypes + XListFonts( + Display *dpy, + _Xconst char *pat, + int maxNum, + int *numNames + ) + #else + XListFonts(dpy, pat, maxNum, numNames) + Display *dpy; + _Xconst char *pat; + int maxNum; + int *numNames; + #endif /* NeedFunctionPrototypes */ + #else + TkpListFonts(dpy, pat, maxNum, numNames) + Display *dpy; + char *pat; + int maxNum; + int *numNames; + #endif /* USE_OWN_XLSFONT */ + { + TkpFontList *newFontList = NULL; + int new; + Tcl_HashEntry *entry = NULL; + Tcl_HashTable *eTable = NULL; + char **fontList = NULL; + int fontNum = 0; + regexp *compPat = NULL; + char **ret = NULL; + int matches = 0; + int i; + char **found = NULL; + + if (numNames != NULL) *numNames = 0; + + entry = Tcl_CreateHashEntry(&xFontListTable, (char *)dpy, &new); + if (new == 0) { + newFontList = (TkpFontList *)Tcl_GetHashValue(entry); + } else { + newFontList = GetFontListByDisplay(dpy); + if (newFontList == NULL) { + Tcl_DeleteHashEntry(entry); + panic("can't get all font list in X server."); + } + Tcl_SetHashValue(entry, (ClientData)newFontList); + } + fontList = newFontList->nameList; + fontNum = newFontList->numFonts; + eTable = &(newFontList->exactTable); + + if (strchr(pat, '*') == NULL) { + char buf[4096]; + char *bCp = buf; + char *pCp = (char *)pat; + int new; + + entry = Tcl_CreateHashEntry(eTable, (char *)pat, &new); + if (new == 0) { + ret = (char **)ckalloc(sizeof(char *)); + ret[0] = (char *)Tcl_GetHashValue(entry); + if (numNames != NULL) *numNames = 1; + return ret; + } + + while (*pCp != 0) { + if (isalpha(*pCp)) { + *bCp = tolower(*pCp); + } else { + *bCp = *pCp; + } + pCp++; + bCp++; + } + *bCp = 0; + bCp = buf; + found = (char **)bsearch(&bCp, &(fontList[0]), (unsigned int)fontNum, + sizeof(char *), fontComp); + if (found != NULL) { + ret = (char **)ckalloc(sizeof(char *)); + ret[0] = (char *)pat; + if (numNames != NULL) *numNames = 1; + Tcl_SetHashValue(entry, (ClientData)Tk_GetUid(pat)); + return ret; + } else { + /* + * Maybe it is not in '*' list, but X server could say "I + * have this one." + */ + int numList; + #ifdef USE_OWN_XLSFONT + char **nameList = TkUnixXListFonts(dpy, (char *)pat, 1, &numList); + #else + char **nameList = XListFonts(dpy, pat, 1, &numList); + #endif /* USE_OWN_XLSFONT */ + if (nameList != NULL && numList > 0) { + ret = (char **)ckalloc(sizeof(char *)); + ret[0] = (char *)pat; + if (numNames != NULL) *numNames = 1; + Tcl_SetHashValue(entry, (ClientData)Tk_GetUid(pat)); + #ifdef USE_OWN_XLSFONT + TkUnixXFreeFontNames(nameList); + #else + XFreeFontNames(nameList); + #endif /* USE_OWN_XLSFONT */ + return ret; + } + } + + Tcl_DeleteHashEntry(entry); + } + + compPat = TclRegComp(PatternToRegexp(pat)); + if (compPat == NULL) { + panic("regcomp NULL"); + return NULL; + } + ret = (char **)ckalloc(sizeof(char **) * fontNum); + + for (i = 0; i < fontNum; i++) { + if (TclRegExec(compPat, fontList[i], fontList[i]) != 0) { + ret[matches] = fontList[i]; + matches++; + } + } + ckfree(compPat); + + if (matches > 0) { + if (numNames != NULL) *numNames = (matches > maxNum) ? maxNum : matches; + } else { + /* + * Mayhaps resizeable font list. Ask server. + */ + int xNumList; + #ifdef USE_OWN_XLSFONT + char **xNameList = TkUnixXListFonts(dpy, (char *)pat, maxNum, &xNumList); + #else + char **xNameList = XListFonts(dpy, pat, maxNum, &xNumList); + #endif /* USE_OWN_XLSFONT */ + ckfree(ret); + ret = NULL; + if (numNames != NULL) *numNames = xNumList; + if (xNameList != NULL && xNumList > 0) { + new = 0; + entry = Tcl_CreateHashEntry(&needXFreeFontListTable, (char *)xNameList, &new); + if (new == 0) { + panic("Maybe non-freed memory alloc'd by XListFonts()."); + } + Tcl_SetHashValue(entry, (ClientData)xNameList); + ret = xNameList; + } + } + return ret; + } + + int + #ifdef USE_OWN_XLSFONT + #if NeedFunctionPrototypes + XFreeFontNames( + char **list + ) + #else + XFreeFontNames(list) + char **list; + #endif /* NeedFunctionPrototypes */ + #else + TkpFreeFontNames(list) + char **list; + #endif /* USE_OWN_XLSFONT */ + { + Tcl_HashEntry *entry; + + entry = Tcl_FindHashEntry(&needXFreeFontListTable, (char *)list); + if (entry != NULL) { + #ifdef USE_OWN_XLSFONT + TkUnixXFreeFontNames(list); + #else + XFreeFontNames(list); + #endif /* USE_OWN_XLSFONT */ + Tcl_DeleteHashEntry(entry); + } else { + ckfree(list); + } + return 1; + } + + + static int + GetPixelSizeFromFontname(name) + char *name; + { + int i; + char *str = name; + char buf[16]; + int ret = 0; + + for (i = 0; i < XLFD_PIXEL_SIZE; i++) { + str = strchr(str + 1, '-'); + if (str == NULL) break; + } + if (str != NULL) { + str++; + if (*str != 0) { + for (i = 0; i < 16; i++) { + if (str[i] == '-' || str[i] == 0) break; + buf[i] = str[i]; + } + buf[i] = 0; + ret = atoi(buf); + } + } + return ret; + } + + + #define CHARSET_MASK 0x07 + #define IS_ISO8859 0x01 + #define IS_JISX0201 0x02 + #define IS_JISX0208 0x04 + #define IS_OTHER 0x08 + + static int + GetCharsetFromFontname(kName) + char *kName; + { + char *tmp = strrchr(kName, '-'); + if (tmp != NULL) { + tmp--; + while (*tmp != 0 && *tmp != '-') { + tmp--; + } + if (tmp != NULL) { + tmp++; + if (strncasecmp(tmp, "iso8859", 7) == 0) { + return IS_ISO8859; + } else if (strncasecmp(tmp, "jisx0201.1976", 13) == 0) { + return IS_JISX0201; + } else if (strncasecmp(tmp, "jisx0208.1983", 13) == 0) { + return IS_JISX0208; + } + } + } + return IS_OTHER; + } + + + #ifdef XOM_CHECK + static void + DrawDummyWithFontSet(tkwin, fontSet) + Tk_Window tkwin; + XFontSet fontSet; + { + static int dummyInited = 0; + static GC gc = None; + static GC clearGC = None; + static Window w = None; + static Pixmap p = None; + static int screen; + static XGCValues xgc; + static int yPos = 30; + char str[] = "01234 abcde (XFontSet I=<(%F%9%HMQ$NJ8;zNs)"; + + if (dummyInited == 0) { + Display *dpy = Tk_Display(tkwin); + screen = DefaultScreen(dpy); + w = XCreateSimpleWindow(dpy, RootWindow(dpy, screen), 0, 0, 400, 300, 2, + WhitePixel(dpy, screen), + WhitePixel(dpy, screen)); + p = XCreatePixmap(dpy, RootWindow(dpy, screen), 600, 300, DefaultDepth(dpy, screen)); + + gc = XCreateGC(dpy, RootWindow(dpy, screen), 0, &xgc); + XSetForeground(dpy, gc, BlackPixel(dpy, screen)); + XSetBackground(dpy, gc, WhitePixel(dpy, screen)); + XSetFunction(dpy, gc, GXcopy); + + clearGC = XCreateGC(dpy, RootWindow(dpy, screen), 0, &xgc); + XSetFunction(dpy, clearGC, GXcopy); + XSetLineAttributes(dpy, clearGC, 4096, LineSolid, CapButt, JoinBevel); + XSetPlaneMask(dpy, clearGC, AllPlanes); + XSetForeground(dpy, clearGC, WhitePixel(dpy, screen)); + XSetBackground(dpy, clearGC, WhitePixel(dpy, screen)); + + XMapWindow(dpy, w); + XSync(dpy, False); + XDrawLine(dpy, p, clearGC, 0, 150, 400, 150); + + dummyInited = 1; + } + + XClearWindow(Tk_Display(tkwin), w); + XmbDrawString(Tk_Display(tkwin), p, fontSet, gc, 5, yPos, str, strlen(str)); + XSetWindowBackgroundPixmap(Tk_Display(tkwin), w, p); + yPos += 30; + if (yPos >= 300) { + XClearWindow(Tk_Display(tkwin), w); + XDrawLine(Tk_Display(tkwin), p, clearGC, 0, 150, 400, 150); + yPos = 30; + } + } + #endif /* XOM_CHECK */ + + + XFontSet + TkpCreateFontSet(tkwin, fontlist, aName, kName) + Tk_Window tkwin; + char *fontlist; + char *aName; + char *kName; + { + XFontSet newFont = NULL; + TkpFontSetCache *newCache; + int new; + Tcl_HashEntry *entry = NULL; + Tcl_HashEntry *keyEntry = NULL; + TkpFontSetCacheKey key; + + key.name = Tk_GetUid(fontlist); + key.dpy = Tk_Display(tkwin); + entry = Tcl_CreateHashEntry(&xFontSetCacheTable, (char *)&key, &new); + if (new == 0) { + newCache = (TkpFontSetCache *)Tcl_GetHashValue(entry); + newCache->refCount++; + return newCache->xFontSet; + } + + { + char **ml; + int mc; + char *ds; + char fBuf[4096]; + int pix; + int dpi; + char *missingCharset = NULL; + int mCharset = CHARSET_MASK; + int retry = 0; + + mCharset &= ~(GetCharsetFromFontname(aName)); + mCharset &= ~(GetCharsetFromFontname(kName)); + mCharset &= CHARSET_MASK; + + #ifdef FONTSETCACHE_DEBUG + fprintf(stderr, "fSetCacheDebug: loading '%s'.....", key.name); + #endif /* FONTSETCACHE_DEBUG */ + + sprintf(fBuf, "%s, %s", aName, kName); + + doCreate: + newFont = XCreateFontSet(key.dpy, fBuf, &ml, &mc, &ds); + if (mc > 0) { + XFreeStringList(ml); + } + if (newFont != NULL) { + goto createOK; + } + + switch (retry) { + case 0: { + /* + * Well, by specification, XCreateFontSet() should + * return valid XFontSet and missing charset, but it didn't. + * Mayhaps one more charset (jisx0201 or iso8859) is needed. + */ + retry++; + + pix = GetPixelSizeFromFontname(kName); + dpi = TkpGetDPI(tkwin, NULL); + + if (mCharset == IS_ISO8859) { + missingCharset = "ISO8859-1"; + } else if (mCharset == IS_JISX0201) { + missingCharset = "JISX0201.1976-0"; + } else if (mCharset == IS_JISX0208) { + missingCharset = "JISX0208.1983-0"; + } + + sprintf(fBuf, "%s, %s, -*-fixed-medium-r-normal-*-%d-*-%d-%d-*-*-%s", + aName, kName, pix, dpi, dpi, missingCharset); + break; + } + + case 1: { + retry++; + sprintf(fBuf, "%s, %s, -*-fixed-medium-r-normal-*-%d-*-*-*-*-*-%s", + aName, kName, pix, missingCharset); + break; + } + + case 2: { + retry++; + /* + * Try the easyest pattern. + */ + sprintf(fBuf, "-*-fixed-medium-r-normal-*-%d-*-*-*-*-*-*-*", pix); + break; + } + + case 3: { + retry++; + /* + * sucks. + */ + Tcl_DeleteHashEntry(entry); + return NULL; + break; + } + } + goto doCreate; + + createOK: + newCache = (TkpFontSetCache *)ckalloc(sizeof(TkpFontSetCache)); + newCache->name = key.name; + newCache->xFontSet = newFont; + newCache->refCount = 1; + newCache->entry = entry; + + keyEntry = Tcl_CreateHashEntry(&xFontSetKeyTable, (char *)newFont, &new); + if (new == 0) { + panic("display and fontset name is already stored in cache!"); + } + Tcl_SetHashValue(entry, (ClientData)newCache); + Tcl_SetHashValue(keyEntry, (ClientData)newCache); + #ifdef FONTSETCACHE_DEBUG + fprintf(stderr, "done, %s.\n", (newFont != NULL) ? "ok" : "fail"); + #endif /* FONTSETCACHE_DEBUG */ + + #ifdef XOM_CHECK + DrawDummyWithFontSet(tkwin, newFont); + #endif /* XOM_CHECK */ + } + + return newFont; + } + + + void + TkpFreeFontSet(tkwin, xFontSet) + Tk_Window tkwin; + XFontSet xFontSet; + { + Tcl_HashEntry *keyEntry = Tcl_FindHashEntry(&xFontSetKeyTable, (char *)xFontSet); + TkpFontSetCache *val; + + if (keyEntry == NULL) { + panic("uncached font about to free."); + } + val = (TkpFontSetCache *)Tcl_GetHashValue(keyEntry); + val->refCount--; + if (val->refCount == 0) { + XFreeFontSet(Tk_Display(tkwin), val->xFontSet); + Tcl_DeleteHashEntry(val->entry); + Tcl_DeleteHashEntry(keyEntry); + #ifdef FONTSETCACHE_DEBUG + fprintf(stderr, "fSetCacheDebug: free '%s' 0x%08x\n", + val->name, val->xFontSet); + #endif /* FONTSETCACHE_DEBUG */ + ckfree((char *)val); + } + } + + + static int + IncrFontCacheRefCount(fontCache) + TkpFontCache *fontCache; + { + fontCache->refCount++; + if (fontCache->maxRef < fontCache->refCount) { + fontCache->maxRef = fontCache->refCount; + } + return fontCache->refCount; + } + + + static TkpFontNameAliasRec * + CreateFontNameAlias(entry) + Tcl_HashEntry *entry; + { + TkpFontNameAliasRec *ret = (TkpFontNameAliasRec *)ckalloc(sizeof(TkpFontNameAliasRec)); + ret->entry = entry; + ret->next = NULL; + return ret; + } + + + static void + AddFontNameAlias(propCache, name) + TkpFontCache *propCache; + Tk_Uid name; + { + Tcl_HashEntry *aEntry = NULL; + int aNew = 0; + TkpFontCacheKey aKey; + TkpFontNameAliasRec *aNameRec = NULL; + + aKey.dpy = propCache->dpy; + aKey.name = name; + aEntry = Tcl_CreateHashEntry(&xFontCacheTable, (char *)&aKey, &aNew); + if (aNew == 0) { + return; + } + aNameRec = CreateFontNameAlias(aEntry); + propCache->aTail->next = aNameRec; + propCache->aTail = aNameRec; + + #ifdef FONTCACHE_DEBUG + { + TkpFontNameAliasRec *tmp = propCache->alias; + TkpFontCacheKey *key; + while (tmp != NULL) { + key = (TkpFontCacheKey *)Tcl_GetHashKey(&xFontCacheTable, tmp->entry); + fprintf(stderr, "\tdebug: alias entry '%s'\n", key->name); + tmp = tmp->next; + } + fprintf(stderr, "\n"); + } + #endif /* FONTCACHE_DEBUG */ + + Tcl_SetHashValue(aEntry, (ClientData)propCache); + } + + + static Tk_Uid + FontnameLower(name) + char *name; + { + char buf[1024]; + char *pBuf = buf; + + while (*name != '\0' && isspace(UCHAR(*name))) { + name++; + } + while (*name != '\0') { + if (isalpha(*name)) { + *pBuf = tolower(*name); + } else { + *pBuf = *name; + } + pBuf++; + name++; + } + *pBuf = 0; + + return Tk_GetUid(buf); + } + + + Tk_Uid + TkpFindFontnameFromFontStruct(tkwin, xFontPtr) + Tk_Window tkwin; + XFontStruct *xFontPtr; + { + Display *dpy = Tk_Display(tkwin); + Tcl_HashSearch search; + TkpFontCache *cache; + Tcl_HashEntry *entry; + + for (entry = Tcl_FirstHashEntry(&xFontCacheTable, &search); + entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + cache = (TkpFontCache *)Tcl_GetHashValue(entry); + if (cache == NULL) { + panic("invalid cache data exists."); + } + if (cache->dpy == dpy && + cache->xFontPtr == xFontPtr) { + return cache->name; + } + } + return NULL; + } + + + XFontStruct * + #ifdef USE_OWN_XLQFONT + #if NeedFunctionPrototypes + XLoadQueryFont( + Display *dpy, + _Xconst char *name + ) + #else + XLoadQueryFont(dpy, name) + Display *dpy; + _Xconst char *name; + #endif /* NeedFunctionPrototypes */ + #else + TkpLoadQueryFont(dpy, name) + Display *dpy; + char *name; + #endif /* USE_OWN_XLQFONT */ + { + XFontStruct *newFont = NULL; + TkpFontCache *newCache = NULL; + Tcl_HashEntry *gnEntry = NULL; + Tk_Uid givenName = FontnameLower(name); + TkpFontCacheKey key; + int nHyphn = 0; + int nAsta = 0; + int hasSpace = (strchr(givenName, ' ') != NULL) ? 1 : 0; + char *tmp; + + if ((givenName[0] != '*' && + givenName[0] != '-' && + hasSpace == 1) || + !(isprint(givenName[0]))) { + return NULL; + } + + key.name = givenName; + key.dpy = dpy; + + gnEntry = Tcl_FindHashEntry(&xFontCacheTable, (char *)&key); + if (gnEntry != NULL) { + newCache = (TkpFontCache *)Tcl_GetHashValue(gnEntry); + IncrFontCacheRefCount(newCache); + return newCache->xFontPtr; + } + + tmp = givenName; + while (*tmp != '\0') { + if (*tmp == '-') { + nHyphn++; + } else if (*tmp == '*') { + nAsta++; + } + tmp++; + } + + if (nHyphn >= 13 && nAsta <= 10) { + char **candNames = NULL; + int numCand = 0; + + #ifdef USE_OWN_XLSFONT + candNames = XListFonts(dpy, givenName, 100000, &numCand); + #else + candNames = TkpListFonts(dpy, givenName, 100000, &numCand); + #endif /* USE_OWN_XLSFONT */ + if (numCand > 0) { + int i; + Tcl_HashEntry *cEntry; + for (i = 0; i < numCand; i++) { + key.name = FontnameLower(candNames[i]); + cEntry = Tcl_FindHashEntry(&xFontCacheTable, (char *)&key); + if (cEntry != NULL) { + newCache = (TkpFontCache *)Tcl_GetHashValue(cEntry); + if (givenName != key.name) { + AddFontNameAlias(newCache, givenName); + } + IncrFontCacheRefCount(newCache); + #ifdef USE_OWN_XLSFONT + XFreeFontNames(candNames); + #else + TkpFreeFontNames(candNames); + #endif /* USE_OWN_XLSFONT */ + return newCache->xFontPtr; + } + } + #ifdef USE_OWN_XLSFONT + XFreeFontNames(candNames); + #else + TkpFreeFontNames(candNames); + #endif /* USE_OWN_XLSFONT */ + } + } + + #ifdef USE_OWN_XLQFONT + if ((newFont = TkUnixXLoadQueryFont(dpy, givenName)) != NULL) { + #else + if ((newFont = XLoadQueryFont(dpy, givenName)) != NULL) { + #endif /* USE_OWN_XLQFONT */ + XFontStruct *retFont = NULL; + unsigned long atom = 0L; + char *propName; + Tk_Uid pName; + int pnNew = 0; + Tcl_HashEntry *pnEntry = NULL; + + /* + * Check whether the property name of the font is already cached or not. + */ + if (XGetFontProperty(newFont, XA_FONT, &atom) != True) { + /* + * Few X server doesn't generate XA_FONT atom for the newFont ??? + */ + pName = givenName; + } else { + propName = XGetAtomName(dpy, atom); + #ifdef CHECK_XLFD + pName = FontnameLower(NormalizeXLFD(propName)); + #else + pName = FontnameLower(propName); + #endif /* CHECK_XLFD */ + XFree(propName); + } + + key.name = pName; + key.dpy = dpy; + pnEntry = Tcl_CreateHashEntry(&xFontCacheTable, (char *)&key, &pnNew); + if (pnNew == 1) { + /* + * Add an entry for property name of the font. + */ + Tcl_HashEntry *keyEntry = NULL; + int keyNew = 0; + newCache = (TkpFontCache *)ckalloc(sizeof(TkpFontCache)); + newCache->name = pName; + newCache->dpy = dpy; + newCache->xFontPtr = newFont; + newCache->refCount = 1; + newCache->maxRef = 1; + newCache->aTail = newCache->alias = CreateFontNameAlias(pnEntry); + newCache->toBeFree = 0; + Tcl_SetHashValue(pnEntry, (ClientData)newCache); + + keyEntry = Tcl_CreateHashEntry(&xFontKeyTable, (char *)newFont, &keyNew); + if (keyNew == 0) { + panic("display and fontname is already stored in cache!"); + } + Tcl_SetHashValue(keyEntry, (ClientData)newCache); + + #ifdef FONTCACHE_DEBUG + fprintf(stderr, "fCacheDebug: load '%s' 0x%08x\n", + pName, newFont); + #endif /* FONTCACHE_DEBUG */ + retFont = newFont; + } else /* get prop entry */ { + /* + * Cached entry of the font (property name) is found. + * Add an entry for given name of the font and return font + * struct of property name. + */ + + newCache = (TkpFontCache *)Tcl_GetHashValue(pnEntry); + + if (newCache->xFontPtr != newFont) { + #ifdef USE_OWN_XLQFONT + TkUnixXFreeFont(dpy, newFont); + #else + XFreeFont(dpy, newFont); + #endif /* USE_OWN_XLQFONT */ + } + IncrFontCacheRefCount(newCache); + retFont = newCache->xFontPtr; + } + + if (givenName != pName) { + /* + * Add an entry for given name of the font. + */ + AddFontNameAlias(newCache, givenName); + #ifdef FONTCACHE_DEBUG + fprintf(stderr, "fCacheDebug: load '%s' 0x%08x (only entry)\n", + givenName, newFont); + #endif /* FONTCACHE_DEBUG */ + } + return retFont; + } + + return NULL; + } + + + static void + DeleteFontCache(fontCache) + TkpFontCache *fontCache; + { + TkpFontNameAliasRec *alias, *next; + TkpFontCacheKey *tmp; + + if (fontCache->refCount > 0) { + panic("Refernced font cache is about to free"); + } + alias = fontCache->alias; + if (alias == NULL) { + panic("Font cache has no name"); + } + if (alias->entry == NULL) { + panic("Font cache has no font cache entry"); + } + + while (alias != NULL) { + tmp = (TkpFontCacheKey *)Tcl_GetHashKey(&xFontCacheTable, alias->entry); + Tcl_DeleteHashEntry(alias->entry); + next = alias->next; + ckfree(alias); + alias = next; + } + + #ifdef USE_OWN_XLQFONT + TkUnixXFreeFont(fontCache->dpy, fontCache->xFontPtr); + #else + XFreeFont(fontCache->dpy, fontCache->xFontPtr); + #endif /* USE_OWN_XLQFONT */ + + ckfree(fontCache); + } + + + #ifdef USE_OWN_XLQFONT + int + #if NeedFunctionPrototypes + XFreeFont( + Display *dpy, + XFontStruct *xFontPtr + ) + #else + XFreeFont(dpy, xFontPtr) + Display *dpy; + XFontStruct *xFontPtr; + #endif /* NeedFunctionPrototypes */ + #else + void + TkpFreeFont(dpy, xFontPtr) + Display *dpy; + XFontStruct *xFontPtr; + #endif /* USE_OWN_XLQFONT */ + { + Tcl_HashEntry *keyEntry = Tcl_FindHashEntry(&xFontKeyTable, (char *)xFontPtr); + TkpFontCache *val; + + if (keyEntry == NULL) { + #ifdef FONTCACHE_DEBUG + unsigned long atom; + Tcl_HashEntry *entry; + char *name; + Tk_Uid pName; + TkpFontCacheKey key; + + if (XGetFontProperty(xFontPtr, XA_FONT, &atom) != True) { + goto checkFail; + } + name = XGetAtomName(dpy, atom); + #ifdef CHECK_XLFD + pName = FontnameLower(NormalizeXLFD(name)); + #else + pName = FontnameLower(name); + #endif /* CHECK_XLFD */ + XFree(name); + + fprintf(stderr, "debug: uncached '%s' free.. \n", pName); + + key.name = pName; + key.dpy = dpy; + entry = Tcl_FindHashEntry(&xFontCacheTable, (char *)&key); + if (entry == NULL) { + fprintf(stderr, "debug: OK, not in hash.\n"); + } else { + fprintf(stderr, "debug: ??? in hash !!\n"); + val = Tcl_GetHashValue(entry); + fprintf(stderr, "debug: in hash '%s', 0x%08x\n", val->name, val->xFontPtr); + } + checkFail: + #endif /* FONTCACHE_DEBUG */ + panic("uncached font about to free."); + } + val = (TkpFontCache *)Tcl_GetHashValue(keyEntry); + val->refCount--; + if (val->refCount <= 0) { + if (val->maxRef > 1) { + #ifdef FONTCACHE_DEBUG + fprintf(stderr, "fCacheDebug: free '%s' 0x%08x\n", + val->name, val->xFontPtr); + #endif /* FONTCACHE_DEBUG */ + DeleteFontCache(val); + Tcl_DeleteHashEntry(keyEntry); + } else { + val->refCount = 0; + } + } + #ifdef USE_OWN_XLQFONT + return 1; + #endif /* USE_OWN_XLQFONT */ + } + + + static void + DumpFontCache(dpy, resultPtr) + Display *dpy; + Tcl_Obj *resultPtr; + { + Tcl_HashSearch search; + Tcl_HashEntry *entry = NULL; + TkpFontCache *fCache = NULL; + TkpFontCacheKey *key = NULL; + char buf[4096]; + + for (entry = Tcl_FirstHashEntry(&xFontCacheTable, &search); + entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + fCache = (TkpFontCache *)Tcl_GetHashValue(entry); + if (fCache == NULL) { + panic("invalid cache data exists."); + } + key = (TkpFontCacheKey *)Tcl_GetHashKey(&xFontCacheTable, entry); + if (key == NULL) { + panic("invalid cache key exists."); + } + if (dpy == NULL || key->dpy == dpy) { + sprintf(buf, "{{%s} 0x%08lx %d} ", + key->name, (unsigned long int)fCache->xFontPtr, fCache->refCount); + Tcl_AppendStringsToObj(resultPtr, buf, NULL); + } + } + } + + + int + TkpFreeFontCache(interp, tkwin, doClear) + Tcl_Interp *interp; + Tk_Window tkwin; + int doClear; + { + Display *dpy = NULL; + Tcl_HashSearch search; + Tcl_HashEntry *entry = NULL; + TkpFontCache *fCache = NULL; + Tcl_Obj *resultPtr = NULL; + int deleteCount = 0; + + if (interp != NULL) { + resultPtr = Tcl_GetObjResult(interp); + } + if (tkwin != NULL) { + dpy = Tk_Display(tkwin); + } + + if (doClear == -1) { + if (resultPtr != NULL) { + DumpFontCache(dpy, resultPtr); + } + return TCL_OK; + } + + for (entry = Tcl_FirstHashEntry(&xFontCacheTable, &search); + entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + + if ((fCache = (TkpFontCache *)Tcl_GetHashValue(entry)) == NULL) { + panic("Invalid font cache"); + } + + if ((dpy == NULL || fCache->dpy == dpy) && fCache->refCount <= 0) { + TkpFontCacheKey *key = (TkpFontCacheKey *)Tcl_GetHashKey(&xFontCacheTable, entry); + + if (resultPtr != NULL) { + Tcl_AppendStringsToObj(resultPtr, "{", key->name, "} ", NULL); + } + + if (doClear == 1) { + if (fCache->name == key->name) { + fCache->toBeFree = 1; + fCache->maxRef = INT_MAX; + deleteCount++; + } + #ifdef FONTCACHE_DEBUG + fprintf(stderr, "fCacheDebug: free '%s' 0x%08x (in cache free)\n", + key->name, fCache->xFontPtr); + #endif /* FONTCACHE_DEBUG */ + } + } + } + + if (doClear == 1 && deleteCount > 0) { + TkpFontCache **del = (TkpFontCache **)ckalloc(sizeof(TkpFontCache *) * deleteCount); + int n = 0; + int i; + TkpFontCacheKey *key; + + for (entry = Tcl_FirstHashEntry(&xFontCacheTable, &search); + entry != NULL; + entry = Tcl_NextHashEntry(&search)) { + + /* + * Only entries that have property name MUST be searched. + */ + fCache = (TkpFontCache *)Tcl_GetHashValue(entry); + key = (TkpFontCacheKey *)Tcl_GetHashKey(&xFontCacheTable, entry); + if (fCache->toBeFree == 1 && + fCache->name == key->name) { + del[n] = fCache; + n++; + } + } + + if (n != deleteCount) { + panic("# of fonts to be delete is invalid."); + } + + for (i = 0; i < n; i++) { + #ifdef USE_OWN_XLQFONT + XFreeFont(del[i]->dpy, del[i]->xFontPtr); + #else + TkpFreeFont(del[i]->dpy, del[i]->xFontPtr); + #endif /* USE_OWN_XLQFONT */ + } + + ckfree(del); + } + + return TCL_OK; + } + + + Tk_Uid + TkpGetFontnameFromFontStruct(xFontPtr) + XFontStruct *xFontPtr; + { + Tcl_HashEntry *keyEntry; + TkpFontCache *val; + + if (xFontPtr == NULL) { + panic("font struct null."); + } + keyEntry = Tcl_FindHashEntry(&xFontKeyTable, (char *)xFontPtr); + if (keyEntry == NULL) { + panic("uncached font reference."); + } + val = (TkpFontCache *)Tcl_GetHashValue(keyEntry); + return val->name; + } + + + Tk_Uid + TkpFindOpendFontname(tkwin, name) + Tk_Window tkwin; + char *name; + { + Tcl_HashEntry *entry = NULL; + TkpFontCacheKey aKey; + + aKey.name = FontnameLower(name); + aKey.dpy = Tk_Display(tkwin); + + entry = Tcl_FindHashEntry(&xFindFontTable, (char *)&aKey); + if (entry != NULL) { + return (Tk_Uid)Tcl_GetHashValue(entry); + } + return NULL; + } + + + void + TkpAddOpendFontname(tkwin, name, opendName) + Tk_Window tkwin; + char *name; + char *opendName; + { + Tcl_HashEntry *entry = NULL; + TkpFontCacheKey aKey; + int aNew = 0; + + aKey.name = FontnameLower(name); + aKey.dpy = Tk_Display(tkwin); + + entry = Tcl_CreateHashEntry(&xFindFontTable, (char *)&aKey, &aNew); + Tcl_SetHashValue(entry, (ClientData)FontnameLower(opendName)); + } + + + void + TkpDeleteOpendFontname(tkwin, name) + Tk_Window tkwin; + char *name; + { + Tcl_HashEntry *entry = NULL; + TkpFontCacheKey aKey; + + aKey.name = FontnameLower(name); + aKey.dpy = Tk_Display(tkwin); + + entry = Tcl_FindHashEntry(&xFindFontTable, (char *)&aKey); + if (entry != NULL) { + Tcl_DeleteHashEntry(entry); + } + } + + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixInit.c ./unix/tkUnixInit.c *** ../../tk8.0.5/unix/tkUnixInit.c Tue Sep 15 03:23:57 1998 --- ./unix/tkUnixInit.c Fri Mar 12 00:39:23 1999 *************** *** 21,26 **** --- 21,31 ---- */ #include "tkInitScript.h" + #ifdef KANJI + static char makeFontScript[] = + "font create Mincho:Helvetica-Bold-12 -compound {{Helvetica -12 bold} -misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0}; font create Mincho:Helvetica-12 -compound {{Helvetica -12} -misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0}; font create Mincho:Courier-12 -compound {{Courier -12} -misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0};\n;if {[string length [info globals doDisplayInit]] > 0} {font failsafe -misc-fixed-medium-r-normal--14-*-*-*-c-*-jisx0208.1983-0; unset doDisplayInit}\n"; + #endif /* KANJI */ + /* *---------------------------------------------------------------------- *************** *** 44,50 **** --- 49,69 ---- TkpInit(interp) Tcl_Interp *interp; { + #ifdef KANJI + Tk_Window mWin = Tk_MainWindow(interp); + int isDpyInitedFirst = 0; + #endif /* KANJI */ TkCreateXEventSource(); + #ifdef KANJI + TkpFontCachePkgInit(); + isDpyInitedFirst = TkpDefaultFontPkgInit(mWin); + if (isDpyInitedFirst == 1) { + Tcl_SetVar(interp, "doDisplayInit", "1", TCL_GLOBAL_ONLY); + } + if (Tcl_Eval(interp, makeFontScript) != TCL_OK) { + panic("Can't make default compound font."); + } + #endif /* KANJI */ return Tcl_Eval(interp, initScript); } diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixInt.h ./unix/tkUnixInt.h *** ../../tk8.0.5/unix/tkUnixInt.h Tue Sep 15 03:23:57 1998 --- ./unix/tkUnixInt.h Fri Mar 12 00:39:23 1999 *************** *** 28,32 **** --- 28,39 ---- EXTERN int TkUnixDoOneXEvent _ANSI_ARGS_((Tcl_Time *timePtr)); EXTERN void TkUnixSetMenubar _ANSI_ARGS_((Tk_Window tkwin, Tk_Window menubar)); + + #ifdef KANJI + EXTERN int TkSetWMCommand _ANSI_ARGS_((TkWindow *winPtr, + char **argv, int argc)); + EXTERN int TkSetWMTextProperty _ANSI_ARGS_((TkWindow *winPtr, + Atom wmatom, char *str)); + #endif /* KANJI */ #endif /* _TKUNIXINT */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixMenu.c ./unix/tkUnixMenu.c *** ../../tk8.0.5/unix/tkUnixMenu.c Tue Sep 15 03:23:57 1998 --- ./unix/tkUnixMenu.c Fri Mar 12 00:39:23 1999 *************** *** 8,16 **** * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkUnixMenu.c,v 1.2 1998/09/14 18:23:57 stanton Exp $ */ #include "tkPort.h" #include "default.h" #include "tkInt.h" --- 8,20 ---- * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * ! * RCS: @(#) $Id: tkUnixMenu.c,v 1.7 1999/03/11 15:39:23 m-hirano Exp $ */ + #ifdef KANJI + #define TK_KANJI_OK + #endif + #include "tkPort.h" #include "default.h" #include "tkInt.h" *************** *** 866,872 **** --- 870,883 ---- *widthPtr = 0; } else { *heightPtr = fmPtr->linespace; + #ifdef TK_KANJI_OK + { + wchar wTmp = 'W'; + *widthPtr = Tk_TextWidth(tkfont, &wTmp, 1); + } + #else *widthPtr = Tk_TextWidth(tkfont, "W", -1); + #endif /* TK_KANJI_OK */ } } *************** *** 1419,1425 **** --- 1430,1443 ---- */ Tk_GetFontMetrics(menuPtr->tkfont, &menuMetrics); + #ifdef TK_KANJI_OK + { + wchar wTmp = 'M'; + accelSpace = Tk_TextWidth(menuPtr->tkfont, &wTmp, 1); + } + #else accelSpace = Tk_TextWidth(menuPtr->tkfont, "M", 1); + #endif /* TK_KANJI_OK */ for (i = 0; i < menuPtr->numEntries; i++) { mePtr = menuPtr->entries[i]; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixMenubu.c ./unix/tkUnixMenubu.c *** ../../tk8.0.5/unix/tkUnixMenubu.c Tue Sep 15 03:23:57 1998 --- ./unix/tkUnixMenubu.c Fri Mar 12 00:39:24 1999 *************** *** 277,283 **** --- 277,288 ---- width = mbPtr->textWidth; height = mbPtr->textHeight; if (mbPtr->width > 0) { + #ifdef TK_KANJI_OK + wchar wTmp = '0'; + width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, &wTmp, 1); + #else width = mbPtr->width * Tk_TextWidth(mbPtr->tkfont, "0", 1); + #endif /* TK_KANJI_OK */ } if (mbPtr->height > 0) { Tk_FontMetrics fm; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixPort.h ./unix/tkUnixPort.h *** ../../tk8.0.5/unix/tkUnixPort.h Thu Oct 1 04:01:22 1998 --- ./unix/tkUnixPort.h Mon May 10 19:10:29 1999 *************** *** 226,230 **** --- 226,349 ---- */ EXTERN void TclpGetTime _ANSI_ARGS_((Tcl_Time *time)); + + #ifdef KANJI + /* + * Font cache stuff + */ + #ifdef USE_OWN_XLQFONT + EXTERN XFontStruct * TkUnixXLoadQueryFont _ANSI_ARGS_((Display *dpy, char *name)); + EXTERN int TkUnixXFreeFont _ANSI_ARGS_((Display *dpy, XFontStruct *font)); + #else + #ifndef CACHE_INCORE + EXTERN XFontStruct * TkpLoadQueryFont _ANSI_ARGS_((Display *dpy, char *name)); + EXTERN int TkpFreeFont _ANSI_ARGS_((Display *dpy, XFontStruct *font)); + #define XLoadQueryFont(dpy, name) TkpLoadQueryFont(dpy, name) + #define XFreeFont(dpy, font) TkpFreeFont(dpy, font) + #endif /* CACHE_INCORE */ + #endif /* USE_OWN_XLQFONT */ + + #ifdef USE_OWN_XLSFONT + EXTERN char ** TkUnixXListFonts _ANSI_ARGS_((Display *dpy, char *pat, int maxNum, int *numNames)); + EXTERN int TkUnixXFreeFontNames _ANSI_ARGS_((char **list)); + #else + #ifndef CACHE_INCORE + EXTERN char ** TkpListFonts _ANSI_ARGS_((Display *dpy, char *pat, int maxNum, int *numNames)); + EXTERN int TkpFreeFontNames _ANSI_ARGS_((char **list)); + #define XListFonts(dpy, pat, maxNum, numNames) TkpListFonts(dpy, pat, maxNum, numNames) + #define XFreeFontNames(list) TkpFreeFontNames(list) + #endif /* CACHE_INCORE */ + #endif /* USE_OWN_XLSFONT */ + + EXTERN XFontSet TkpCreateFontSet _ANSI_ARGS_ ((Tk_Window tkwin, char *fontlist, char *aName, char *kName)); + EXTERN void TkpFreeFontSet _ANSI_ARGS_ ((Tk_Window tkwin, XFontSet xFontSet)); + + EXTERN int TkpFreeFontCache _ANSI_ARGS_((Tcl_Interp *interp, + Tk_Window tkwin, int doClear)); + + EXTERN void TkpFontCachePkgInit _ANSI_ARGS_((void)); + EXTERN Tk_Uid TkpGetFontnameFromFontStruct _ANSI_ARGS_((XFontStruct *xFontPtr)); + #endif /* KANJI */ + + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + /* Struct keeping input context attributes */ + typedef struct { + int icState; + #define IC_NEVER_USED 0x0000 + #define IC_USED_AT_LEAST_ONETIME 0x0001 + #define IC_ASSOC_WIN_DELETED 0x0002 + #define IC_DESTROYED 0x0004 + #define IC_IN_USE_RITE_NOW 0x0008 + #define SetICState(icAttr, flag) (icAttr)->icState |= (flag) + #define ResetICState(icAttr, flag) (icAttr)->icState &= ~(flag) + #define IsSetICState(icAttr, flag) (((icAttr)->icState & (flag)) == (flag)) + + Tk_Uid style; + XIMStyle styleVal; + + Tk_Uid peArea; + XRectangle peAreaVal; + + Tk_Uid stArea; + XRectangle stAreaVal; + + /* Get only */ + Tk_Uid stPrefArea; + XRectangle stPrefAreaVal; + + Tk_Uid spot; + XPoint spotVal; + + Tk_Uid font; /* A font name in Tk's world. */ + Tk_Uid fontlist; /* A fontset (XFontSet) name of below, in X's world. */ + XFontSet fontset; + + Tk_Uid fg; + unsigned long fgVal; + + Tk_Uid bg; + unsigned long bgVal; + + int isChanged; + #define IM_NOTHING_CHANGE 0x0000 + #define IM_STYLE_CHANGE 0x0001 + #define IM_PREEDITAREA_CHANGE 0x0002 + #define IM_STATUSAREA_CHANGE 0x0004 + #define IM_SPOT_CHANGE 0x0008 + #define IM_FONT_CHANGE 0x0010 + #define IM_COLOR_CHANGE 0x0020 + + int doPreedit; + int doStatus; + + XIMCallback peCB[4]; + #define IM_PEStartCB 0 + #define IM_PEDoneCB 1 + #define IM_PEDrawCB 2 + #define IM_PECaretCB 3 + XIMCallback stCB[3]; + #define IM_STStartCB 0 + #define IM_STDoneCB 1 + #define IM_STDrawCB 2 + + Tk_Uid callbackCmd; /* tcl script called when above + callback is activated. */ + } TkpICAttribute; + + /* + * Supported IC attributes flags. + */ + #define IM_SUPPORT_NOTHING 0x0000 + #define IM_SUPPORT_PREEDITAREA 0x0001 + #define IM_SUPPORT_STATUSAREA 0x0002 + #define IM_SUPPORT_AREA 0x0004 + #define IM_SUPPORT_AREANEEDED 0x0008 + #define IM_SUPPORT_SPOT 0x0010 + #define IM_SUPPORT_FONT 0x0020 + #define IM_SUPPORT_COLOR 0x0040 + + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ #endif /* _UNIXPORT */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixScale.c ./unix/tkUnixScale.c *** ../../tk8.0.5/unix/tkUnixScale.c Tue Sep 15 03:23:57 1998 --- ./unix/tkUnixScale.c Fri Mar 12 00:39:24 1999 *************** *** 255,260 **** --- 255,264 ---- y = TkpValueToPixel(scalePtr, value) + fm.ascent/2; sprintf(valueString, scalePtr->format, value); length = strlen(valueString); + #if defined(KANJI) && defined(TK_KANJI_OK) && defined(TK_REPLACE_TO_KANJIFUNC) + #undef Tk_TextWidth + #undef Tk_DrawChars + #endif /* KANJI && TK_KANJI_OK && TK_REPLACE_TO_KANJIFUNC */ width = Tk_TextWidth(scalePtr->tkfont, valueString, length); /* *************** *** 268,275 **** --- 272,289 ---- if ((y + fm.descent) > (Tk_Height(tkwin) - scalePtr->inset - SPACING)) { y = Tk_Height(tkwin) - scalePtr->inset - SPACING - fm.descent; } + #ifdef TK_KANJI_OK + /* Since Tk_DrawWChar()(XDrawText) and Tk_DrawChar()(XDrawString) + * are used together in scale widget, we have to reset font only + * here. */ + XSetFont(scalePtr->display, scalePtr->textGC, Tk_FontId(scalePtr->tkfont)); + #endif /* TK_KANJI_OK */ Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC, scalePtr->tkfont, valueString, length, rightEdge - width, y); + #if defined(KANJI) && defined(TK_KANJI_OK) && defined(TK_REPLACE_TO_KANJIFUNC) + #define Tk_TextWidth Tk_WTextWidth + #define Tk_DrawChars Tk_DrawWChars + #endif /* KANJI && TK_KANJI_OK && TK_REPLACE_TO_KANJIFUNC */ } /* *************** *** 455,460 **** --- 469,478 ---- y = top + fm.ascent; sprintf(valueString, scalePtr->format, value); length = strlen(valueString); + #if defined(KANJI) && defined(TK_KANJI_OK) && defined(TK_REPLACE_TO_KANJIFUNC) + #undef Tk_TextWidth + #undef Tk_DrawChars + #endif /* KANJI && TK_KANJI_OK && TK_REPLACE_TO_KANJIFUNC */ width = Tk_TextWidth(scalePtr->tkfont, valueString, length); /* *************** *** 471,476 **** --- 489,498 ---- } Tk_DrawChars(scalePtr->display, drawable, scalePtr->textGC, scalePtr->tkfont, valueString, length, x, y); + #if defined(KANJI) && defined(TK_KANJI_OK) && defined(TK_REPLACE_TO_KANJIFUNC) + #define Tk_TextWidth Tk_WTextWidth + #define Tk_DrawChars Tk_DrawWChars + #endif /* KANJI && TK_KANJI_OK && TK_REPLACE_TO_KANJIFUNC */ } /* diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixSelect.c ./unix/tkUnixSelect.c *** ../../tk8.0.5/unix/tkUnixSelect.c Tue Sep 15 03:23:57 1998 --- ./unix/tkUnixSelect.c Thu Mar 18 22:38:52 1999 *************** *** 107,113 **** --- 107,117 ---- */ int + #ifdef KANJI + TkSelGetSelection(interp, tkwin, selection, target, proc, clientData, typeAtomPtr) + #else TkSelGetSelection(interp, tkwin, selection, target, proc, clientData) + #endif /* KANJI */ Tcl_Interp *interp; /* Interpreter to use for reporting * errors. */ Tk_Window tkwin; /* Window on whose behalf to retrieve *************** *** 119,124 **** --- 123,131 ---- Tk_GetSelProc *proc; /* Procedure to call to process the * selection, once it has been retrieved. */ ClientData clientData; /* Arbitrary value to pass to proc. */ + #ifdef KANJI + Atom *typeAtomPtr; + #endif /* KANJI */ { TkSelRetrievalInfo retr; TkWindow *winPtr = (TkWindow *) tkwin; *************** *** 148,153 **** --- 155,163 ---- retr.result = -1; retr.idleTime = 0; retr.nextPtr = pendingRetrievals; + #ifdef KANJI + retr.type = None; + #endif /* KANJI */ pendingRetrievals = &retr; /* *************** *** 173,178 **** --- 183,193 ---- Tcl_DoOneEvent(0); } Tcl_DeleteTimerHandler(retr.timeout); + #ifdef KANJI + if (typeAtomPtr != NULL) { + *typeAtomPtr = retr.type; + } + #endif /* KANJI */ /* * Unregister the information about the selection retrieval *************** *** 301,307 **** --- 316,332 ---- } else { incrPtr->offsets[i] += numItems; } + #ifdef KANJI + if (formatType == XA_STRING || + /* + * formatType TEXT is not valid, but format must be 8. + */ + formatType == Tk_UsefulAtom(incrPtr->winPtr, textAtom) || + formatType == Tk_UsefulAtom(incrPtr->winPtr, compoundTextAtom) || + formatType == Tk_UsefulAtom(incrPtr->winPtr, cStringAtom)) { + #else if (formatType == XA_STRING) { + #endif /* KANJI */ propPtr = (char *) buffer; format = 8; } else { *************** *** 409,414 **** --- 434,446 ---- 0, MAX_PROP_WORDS, False, (Atom) AnyPropertyType, &type, &format, &numItems, &bytesAfter, (unsigned char **) &propInfo); + #ifdef KANJI + retrPtr->type = type; + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: selection returned type = '%s'\n", + Tk_GetAtomName(tkwin, type)); + #endif /* SELECTION_DEBUG */ + #endif /* KANJI */ if ((result != Success) || (type == None)) { return; } *************** *** 419,426 **** --- 451,464 ---- XFree(propInfo); return; } + #ifdef KANJI + if ((type == XA_STRING) || (type == dispPtr->textAtom) || + (type == dispPtr->compoundTextAtom) || + (type == dispPtr->cStringAtom)) { + #else if ((type == XA_STRING) || (type == dispPtr->textAtom) || (type == dispPtr->compoundTextAtom)) { + #endif /* KANJI */ if (format != 8) { sprintf(retrPtr->interp->result, "bad format for string selection: wanted \"8\", got \"%d\"", *************** *** 581,586 **** --- 619,628 ---- TkSelectionInfo *infoPtr; TkSelInProgress ip; + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: get SelectionRequest event target:'%s'.\n", + Tk_GetAtomName((Tk_Window)winPtr, eventPtr->target)); + #endif /* SELECTION_DEBUG */ errorHandler = Tk_CreateErrorHandler(eventPtr->display, -1, -1,-1, (int (*)()) NULL, (ClientData) NULL); *************** *** 697,702 **** --- 739,749 ---- ip.nextPtr = pendingPtr; pendingPtr = &ip; type = selPtr->format; + #ifdef SELECTION_DEBUG + fprintf(stderr, "debug: selPtr target:'%s' format:'%s'\n", + Tk_GetAtomName((Tk_Window)winPtr, selPtr->target), + Tk_GetAtomName((Tk_Window)winPtr, selPtr->format)); + #endif /* SELECTION_DEBUG */ numItems = (*selPtr->proc)(selPtr->clientData, 0, (char *) buffer, TK_SEL_BYTES_AT_ONCE); pendingPtr = ip.nextPtr; *************** *** 731,737 **** --- 778,794 ---- propPtr = (char *) buffer; format = 32; incr.offsets[i] = 0; + #ifdef KANJI + } else if (type == XA_STRING || + /* + * type TEXT is not valid, but format must be 8. + */ + type == Tk_UsefulAtom(winPtr, textAtom) || + type == Tk_UsefulAtom(winPtr, compoundTextAtom) || + type == Tk_UsefulAtom(winPtr, cStringAtom)) { + #else } else if (type == XA_STRING) { + #endif /* KANJI */ propPtr = (char *) buffer; format = 8; } else { *************** *** 889,894 **** --- 946,954 ---- retrPtr->result = TCL_OK; } else if ((type == XA_STRING) || (type == retrPtr->winPtr->dispPtr->textAtom) + #ifdef KANJI + || (type == retrPtr->winPtr->dispPtr->cStringAtom) + #endif /* KANJI */ || (type == retrPtr->winPtr->dispPtr->compoundTextAtom)) { if (format != 8) { Tcl_SetResult(retrPtr->interp, (char *) NULL, TCL_STATIC); diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkUnixWm.c ./unix/tkUnixWm.c *** ../../tk8.0.5/unix/tkUnixWm.c Thu Oct 1 08:46:17 1998 --- ./unix/tkUnixWm.c Fri Mar 12 00:39:26 1999 *************** *** 476,482 **** --- 476,484 ---- * be mapped. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; + #ifndef KANJI XTextProperty textProp; + #endif /* KANJI */ char *string; if (wmPtr->flags & WM_NEVER_MAPPED) { *************** *** 498,513 **** --- 500,523 ---- */ string = (wmPtr->title != NULL) ? wmPtr->title : winPtr->nameUid; + #ifdef KANJI + (void) TkSetWMTextProperty(winPtr, XA_WM_NAME, string); + #else if (XStringListToTextProperty(&string, 1, &textProp) != 0) { XSetWMName(winPtr->display, wmPtr->wrapperPtr->window, &textProp); XFree((char *) textProp.value); } + #endif /* KANJI */ TkWmSetClass(winPtr); if (wmPtr->iconName != NULL) { + #ifdef KANJI + (void) TkSetWMTextProperty(winPtr, XA_WM_ICON_NAME, wmPtr->iconName); + #else XSetIconName(winPtr->display, wmPtr->wrapperPtr->window, wmPtr->iconName); + #endif /* KANJI */ } if (wmPtr->master != None) { *************** *** 519,534 **** --- 529,553 ---- UpdateHints(winPtr); UpdateWmProtocols(wmPtr); if (wmPtr->cmdArgv != NULL) { + #ifdef KANJI + (void) TkSetWMCommand(winPtr, wmPtr->cmdArgv, wmPtr->cmdArgc); + #else XSetCommand(winPtr->display, wmPtr->wrapperPtr->window, wmPtr->cmdArgv, wmPtr->cmdArgc); + #endif /* KANJI */ } if (wmPtr->clientMachine != NULL) { + #ifdef KANJI + (void) TkSetWMTextProperty(winPtr, XA_WM_CLIENT_MACHINE, + wmPtr->clientMachine); + #else if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp) != 0) { XSetWMClientMachine(winPtr->display, wmPtr->wrapperPtr->window, &textProp); XFree((char *) textProp.value); } + #endif /* KANJI */ } } if (wmPtr->hints.initial_state == WithdrawnState) { *************** *** 889,894 **** --- 908,917 ---- ckalloc((unsigned) (strlen(argv[3]) + 1)); strcpy(wmPtr->clientMachine, argv[3]); if (!(wmPtr->flags & WM_NEVER_MAPPED)) { + #ifdef KANJI + return TkSetWMTextProperty(winPtr, XA_WM_CLIENT_MACHINE, + wmPtr->clientMachine); + #else XTextProperty textProp; if (XStringListToTextProperty(&wmPtr->clientMachine, 1, &textProp) != 0) { *************** *** 896,901 **** --- 919,925 ---- &textProp); XFree((char *) textProp.value); } + #endif /* KANJI */ } } else if ((c == 'c') && (strncmp(argv[1], "colormapwindows", length) == 0) && (length >= 3)) { *************** *** 1010,1017 **** --- 1034,1045 ---- wmPtr->cmdArgc = cmdArgc; wmPtr->cmdArgv = cmdArgv; if (!(wmPtr->flags & WM_NEVER_MAPPED)) { + #ifdef KANJI + (void) TkSetWMCommand(winPtr, wmPtr->cmdArgv, wmPtr->cmdArgc); + #else XSetCommand(winPtr->display, wmPtr->wrapperPtr->window, cmdArgv, cmdArgc); + #endif /* KANJI */ } } else if ((c == 'd') && (strncmp(argv[1], "deiconify", length) == 0)) { if (argc != 3) { *************** *** 1331,1338 **** --- 1359,1370 ---- wmPtr->iconName = ckalloc((unsigned) (strlen(argv[3]) + 1)); strcpy(wmPtr->iconName, argv[3]); if (!(wmPtr->flags & WM_NEVER_MAPPED)) { + #ifdef KANJI + return TkSetWMTextProperty(winPtr, XA_WM_ICON_NAME, wmPtr->iconName); + #else XSetIconName(winPtr->display, wmPtr->wrapperPtr->window, wmPtr->iconName); + #endif /* KANJI */ } } } else if ((c == 'i') && (strncmp(argv[1], "iconposition", length) == 0) *************** *** 1733,1738 **** --- 1765,1773 ---- wmPtr->title = ckalloc((unsigned) (strlen(argv[3]) + 1)); strcpy(wmPtr->title, argv[3]); if (!(wmPtr->flags & WM_NEVER_MAPPED)) { + #ifdef KANJI + return TkSetWMTextProperty(winPtr, XA_WM_NAME, wmPtr->title); + #else XTextProperty textProp; if (XStringListToTextProperty(&wmPtr->title, 1, *************** *** 1741,1746 **** --- 1776,1782 ---- &textProp); XFree((char *) textProp.value); } + #endif /* KANJI */ } } } else if ((c == 't') && (strncmp(argv[1], "transient", length) == 0) *************** *** 3441,3446 **** --- 3477,3485 ---- int x, y, childX, childY, tmpx, tmpy, bd; WmInfo *wmPtr; TkWindow *winPtr, *childPtr, *nextPtr; + #ifdef BUGFIX + Tk_ErrorHandler eHdlr = NULL; + #endif /* BUGFIX */ /* * Step 1: scan the list of toplevel windows to see if there is a *************** *** 3479,3490 **** --- 3518,3543 ---- * the toplevel. */ + #ifdef BUGFIX + /* + * If really want to do panic(), have to avoid calling native + * error handler in X. + */ + eHdlr = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, + (Tk_ErrorProc *)NULL, (ClientData)NULL); + #endif /* BUGFIX */ while (1) { if (XTranslateCoordinates(Tk_Display(tkwin), parent, window, x, y, &childX, &childY, &child) == False) { + #ifdef BUGFIX + Tk_DeleteErrorHandler(eHdlr); + #endif /* BUGFIX */ panic("Tk_CoordsToWindow got False return from XTranslateCoordinates"); } if (child == None) { + #ifdef BUGFIX + Tk_DeleteErrorHandler(eHdlr); + #endif /* BUGFIX */ return NULL; } for (wmPtr = firstWmPtr; wmPtr != NULL; wmPtr = wmPtr->nextPtr) { *************** *** 3506,3511 **** --- 3559,3570 ---- } gotToplevel: + #ifdef BUGFIX + if (eHdlr != NULL) { + Tk_DeleteErrorHandler(eHdlr); + eHdlr = NULL; + } + #endif /* BUGFIX */ winPtr = wmPtr->winPtr; if (winPtr->mainPtr != ((TkWindow *) tkwin)->mainPtr) { return NULL; *************** *** 4815,4820 **** if ((winPtr == NULL) || (wmPtr == NULL)) { return NULL; } ! return wmPtr->wrapperPtr; } --- 4874,5028 ---- if ((winPtr == NULL) || (wmPtr == NULL)) { return NULL; } ! #ifdef KANJI ! if (Tk_WindowId(winPtr) == ! RootWindow(Tk_Display(winPtr), Tk_ScreenNumber(winPtr))) { ! return winPtr; ! } else { ! return wmPtr->wrapperPtr; ! } ! #else return wmPtr->wrapperPtr; + #endif /* KANJI */ + } + #ifdef KANJI + + /* + *---------------------------------------------------------------------- + * + * TkSetWMCommand -- + * + * If 'argv' contain kanji characters, covert them to COMPOUND_TEXT + * and call XSetTextProperty. Otherwise, just call XSetCommand. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + int + TkSetWMCommand(winPtr, argv, argc) + TkWindow *winPtr; + char **argv; + int argc; + { + int i; + int havekanji = 0; + int kanjiCode; + Window win = winPtr->wmInfoPtr->wrapperPtr->window; + int aLen; + + for (i = 0; i < argc; i++) { + aLen = strlen(argv[i]); + if (Tcl_KanjiString((Tcl_Interp *) NULL, argv[i], argv[i] + aLen, &kanjiCode) + != TCL_NOT_KANJI) { + havekanji = 1; + break; + } + } + + if (!havekanji) { + XSetCommand(winPtr->display, win, argv, argc); + } else { /* str have kanji. set TEXT as COMPOUND_TEXT. */ + XTextProperty textProp; + wchar *wstr; + unsigned char *tmp; + int len = 0, olen = 0; + + if (!(textProp.value = (unsigned char *)ckalloc(sizeof(char)))) { + return TCL_ERROR; + } + for (i = 0; i < argc; i++) { + aLen = strlen(argv[i]); + (void) Tcl_KanjiString((Tcl_Interp *) NULL, argv[i], argv[i] + aLen, &kanjiCode); + if (!(wstr = + (wchar *)ckalloc((unsigned)(Tcl_KanjiEncode(kanjiCode, argv[i], NULL) + 1) + * sizeof(wchar)))) { + return TCL_ERROR; + } + (void) Tcl_KanjiEncode(kanjiCode, argv[i], wstr); + tmp = (unsigned char *) Tk_WStrToCtext(wstr, -1); + len += strlen(tmp); + if (!(textProp.value = (unsigned char *) ckrealloc(textProp.value, + (unsigned int)(++len)))) { + ckfree((char *) wstr); + ckfree((char *) tmp); + return TCL_ERROR; + } + strcpy(&(textProp.value[olen]), tmp); + ckfree((char *) tmp); + ckfree((char *) wstr); + olen = len; + } + textProp.encoding = Tk_UsefulAtom(winPtr, compoundTextAtom); + textProp.format = 8; + textProp.nitems = len; + XSetTextProperty(winPtr->display, win, &textProp, XA_WM_COMMAND); + ckfree((char *) textProp.value); + } + return TCL_OK; + } + + /* + *---------------------------------------------------------------------- + * + * TkSetWMTextProperty -- + * + * If 'str' contain kanji characters, convert them to COMPOUND_TEXT + * and call XSetTextProperty. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + int + TkSetWMTextProperty(winPtr, wmatom, str) + TkWindow *winPtr; + Atom wmatom; + char *str; + { + int kanjiCode; + Window win = winPtr->wmInfoPtr->wrapperPtr->window; + char *end = str + strlen(str); + + if (wmatom != XA_WM_CLIENT_MACHINE && wmatom != XA_WM_ICON_NAME && + wmatom != XA_WM_NAME) { + return TCL_ERROR; + } + + if (Tcl_KanjiString((Tcl_Interp *) NULL, str, end, &kanjiCode) == TCL_NOT_KANJI) { + XTextProperty textProp; + + if (XStringListToTextProperty(&str, 1, &textProp) != 0) { + XSetTextProperty(winPtr->display, win, &textProp, wmatom); + XFree((char *) textProp.value); + } + } else { /* str have kanji. set TEXT as COMPOUND_TEXT. */ + XTextProperty textProp; + wchar *wstr; + + if (!(wstr = (wchar *) ckalloc( + (unsigned)(Tcl_KanjiEncode(kanjiCode, str, NULL) + 1) * sizeof(wchar)))) { + return TCL_ERROR; + } + (void) Tcl_KanjiEncode(kanjiCode, str, wstr); + textProp.value = (unsigned char *) Tk_WStrToCtext(wstr, -1); + textProp.encoding = Tk_UsefulAtom(winPtr, compoundTextAtom); + textProp.format = 8; + textProp.nitems = strlen(textProp.value); + XSetTextProperty(winPtr->display, win, &textProp, wmatom); + ckfree((char *) textProp.value); + ckfree((char *) wstr); + } + return TCL_OK; } + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/unix/tkXIM.c ./unix/tkXIM.c *** ../../tk8.0.5/unix/tkXIM.c Thu Jan 1 09:00:00 1970 --- ./unix/tkXIM.c Mon May 10 19:10:29 1999 *************** *** 0 **** --- 1,3324 ---- + /* + * tkXIM.c -- + * + * This file contains modules to implement the XIM protocol session. + * + * Author: m-hirano@sra.co.jp + * + * Copyright 1998-1999 Software Research Associates, Inc. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Software Research Associates not be + * used in advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. Software Research + * Associates makes no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + */ + + #ifndef lint + static char rcsid[] = "$Header: /home/m-hirano/cvsroot/tcltk/tk8.0jp/unix/tkXIM.c,v 1.22 1999/05/08 01:06:01 m-hirano Exp $"; + #endif /* !lint */ + + #include "tkPort.h" + #include "tkInt.h" + + #include "tkFont.h" + + #ifdef TK_USE_INPUT_METHODS + #ifdef XIM_IMPROVE + + static XIMStyle GetStyleValueByStyleString _ANSI_ARGS_ ((char *str)); + static char * GetStyleStringByStyleValue _ANSI_ARGS_ ((XIMStyle val)); + static void TkpIMGenericHandler _ANSI_ARGS_ ((ClientData clientData, XEvent *eventPtr)); + static Tk_Uid GetFontNames _ANSI_ARGS_ ((Tcl_Interp *interp, Tk_Window tkwin, char *str, + char **aName, char **kName)); + static Window TkpIMGetICFocusWindow _ANSI_ARGS_ ((XIC ic)); + static XPoint * TkpIMSendSpotLocation _ANSI_ARGS_ ((XIC ic, XPoint *spot)); + static XPoint * TkpIMGetSpotLocation _ANSI_ARGS_ ((XIC ic, XPoint *spot)); + static XRectangle * TkpIMSendArea _ANSI_ARGS_ ((XIC ic, char *attr, XRectangle *rect)); + static XFontSet TkpIMSendFontSet _ANSI_ARGS_ ((XIC ic, char *attr, XFontSet fontset)); + static int TkpIMSendColor _ANSI_ARGS_ ((XIC ic, + unsigned long fg, unsigned long bg, Colormap cmap)); + static TkWindow * TkpIMGetPreferredArea _ANSI_ARGS_ ((XIC ic, TkWindow *winPtr)); + + static void DumpICAttribute _ANSI_ARGS_ ((Tcl_Interp *interp, TkWindow *winPtr)); + static int ConfigGetICAttribute _ANSI_ARGS_ ((Tcl_Interp *interp, TkWindow *winPtr, + int objc, Tcl_Obj *CONST objv[])); + static int ConfigSetICAttribute _ANSI_ARGS_ ((Tcl_Interp *interp, TkWindow *winPtr, + int objc, Tcl_Obj *CONST objv[], int force)); + + static XIC TkpCreateIC _ANSI_ARGS_ ((TkWindow *winPtr)); + static void TkpDestroyIC _ANSI_ARGS_ ((TkWindow *winPtr)); + static int TkpConfigIC _ANSI_ARGS_ ((Tcl_Interp *interp, TkWindow *winPtr)); + static int TkpIMSendAttribute _ANSI_ARGS_ ((Tcl_Interp *interp, TkWindow *winPtr)); + static int GenerateAttrVaList _ANSI_ARGS_ ((TkWindow *winPtr, + XVaNestedList *peListPtr, + XVaNestedList *stListPtr)); + static XVaNestedList GenPreeditCallbackVaList _ANSI_ARGS_ ((TkWindow *winPtr)); + static XVaNestedList GenStatusCallbackVaList _ANSI_ARGS_ ((TkWindow *winPtr)); + + static void TkpIMSetBarrier _ANSI_ARGS_((Display *dpy)); + static void TkpIMUnsetBarrier _ANSI_ARGS_((Display *dpy)); + + #define TkIMPreeditMask (XIMPreeditArea|XIMPreeditCallbacks|XIMPreeditPosition|XIMPreeditNothing|XIMPreeditNone) + #define TkIMStatusMask (XIMStatusArea|XIMStatusCallbacks|XIMStatusNothing|XIMStatusNone) + + #define imSupportAttr(disp, X) ( (((disp)->imIcValues) & (X)) == (X) ) + + typedef struct { + char *styleString; + XIMStyle styleVal; + } TkpIMStyle; + + static TkpIMStyle imStyle[] = { + { "PreeditArea", XIMPreeditArea }, + { "PreeditCallbacks", XIMPreeditCallbacks }, + { "PreeditPosition", XIMPreeditPosition }, + { "PreeditNothing", XIMPreeditNothing }, + { "PreeditNone", XIMPreeditNone }, + { "StatusArea", XIMStatusArea }, + { "StatusCallbacks", XIMStatusCallbacks }, + { "StatusNothing", XIMStatusNothing }, + { "StatusNone", XIMStatusNone }, + }; + #define StyleTableSize(a) (sizeof(a) / sizeof(a[0])) + + static XIMStyle + GetStyleValueByStyleString(str) + char *str; + { + int i; + + if (str == NULL || *str == 0) return (XIMStyle)0L; + + for (i = 0; i < StyleTableSize(imStyle); i++) { + if (strcmp(imStyle[i].styleString, str) == 0) { + return imStyle[i].styleVal; + } + } + return (XIMStyle)0L; + } + + + static char imStrBuf[1024]; + static char * + GetStyleStringByStyleValue(val) + XIMStyle val; + { + int len = 0; + int i; + + if (val == (XIMStyle)0L) return NULL; + for (i = 0; i < StyleTableSize(imStyle); i++) { + if (val & imStyle[i].styleVal) { + sprintf(imStrBuf + len, "%s ", imStyle[i].styleString); + len += (strlen(imStyle[i].styleString) + 1); + } + } + if (len == 0) return NULL; + if (imStrBuf[len - 1] == ' ') { + imStrBuf[len - 1] = 0; + } else { + imStrBuf[len] = 0; + } + return imStrBuf; + } + + + static TkWindow * + GetToplevel(winPtr) + TkWindow *winPtr; + { + while (!(winPtr->flags & TK_TOP_LEVEL)) { + winPtr = winPtr->parentPtr; + if (winPtr == NULL) { + return NULL; + } + } + return winPtr; + } + + + static void + TkpIMGenericHandler(clientData, eventPtr) + ClientData clientData; + XEvent *eventPtr; + { + Tk_Window tkwin = (Tk_Window)clientData; + TkWindow *winPtr = (TkWindow *)clientData; + + if (eventPtr->xany.window != Tk_WindowId(tkwin) || + winPtr->inputContext == NULL || + !(winPtr->flags & TK_CHECKED_IC)) { + /* + * Why ME ??? + */ + return; + } + + /* + * Well, should I care about Enter/Leave ? + */ + switch (eventPtr->type) { + case KeyPress: + case FocusIn: { + Window root, child; + int rootX, rootY; + int wX, wY; + unsigned int mask; + + /* + * Care about case mouse pointer is not on winPtr->window. + * In such a case, IM server can't fetch any events from Tk. + */ + + if (XQueryPointer(winPtr->display, + RootWindow(winPtr->display, winPtr->screenNum), + &root, &child, &rootX, &rootY, &wX, &wY, &mask) == True) { + TkWindow *pWin = (TkWindow *)Tk_CoordsToWindow(rootX, rootY, + (Tk_Window)winPtr); + if (pWin != NULL && (pWin->window != winPtr->window)) { + #if 0 + /* + * Code belows are what I REALLY want to do. But, + * in XIMPreeditPosition mode, IM server use the + * focus window as key event source window and as + * PreeditArea window by X11 specification. I want + * IM server to use this focus window ONLY as key + * event source. Means: + * + * o PreeditArea and PreeditPosition take place + * within client window (winPtr->window). + * o KeyPress event source is the window in which + * mouse pointer is (pWin->window). + */ + + if (XSetICValues(winPtr->inputContext, XNFocusWindow, + pWin->window, NULL) != NULL) { + fprintf(stderr, "debugIC: can't set IC focus to pointer window 0x%08x\n", + pWin->window); + } else { + fprintf(stderr, "debugIC: set IC focus to pointer window 0x%08x\n", + pWin->window); + } + #endif + /* + * Check pWin and winPtr are in same toplevel. + * If they are NOT, don't change focus. + */ + TkWindow *pTop = GetToplevel(pWin); + TkWindow *wTop = GetToplevel(winPtr); + if (pTop == wTop) { + TkpChangeFocus(winPtr, 1); + #ifdef XIM_DEBUG + fprintf(stderr, "debugIC: X focus to '%s' 0x%08x\n", winPtr->pathName, + winPtr->window); + #endif /* XIM_DEBUG */ + } + } + } + /* + * Get current focused window. + */ + if (winPtr->dispPtr->lastFocusedIC != winPtr->inputContext) { + #ifdef XIM_DEBUG + fprintf(stderr, "debugIC: IC focus to '%s' 0x%08x\n", winPtr->pathName, + winPtr->window); + #endif /* XIM_DEBUG */ + winPtr->dispPtr->lastFocusedIC = winPtr->inputContext; + XSetICFocus(winPtr->inputContext); + } + break; + } + + case FocusOut: { + winPtr->dispPtr->lastFocusedIC = None; + XUnsetICFocus(winPtr->inputContext); + break; + } + + case DestroyNotify: { + winPtr->dispPtr->lastFocusedIC = None; + XUnsetICFocus(winPtr->inputContext); + SetICState(winPtr->icAttr, (IC_DESTROYED|IC_ASSOC_WIN_DELETED)); + TkpDeleteIMGenericHandler(tkwin); + break; + } + } + } + + + /* + * returned value is Tk_GetUid()'d. + */ + Tk_Uid + GetFontNames(interp, tkwin, str, aNameRet, kNameRet) + Tcl_Interp *interp; + Tk_Window tkwin; + char *str; + char **aNameRet; + char **kNameRet; + { + char *aName = NULL; + char *kName = NULL; + char *ret = NULL; + /* + * Byte length of a font name is smaller than 256. + * (If you doubt it, check Xlib code :^>) + * Maybe 1024 is enuff for room of fontset name. + */ + char fontNames[1024]; + int success = 0; + + Tk_Font tkfont = Tk_GetFont(interp, tkwin, Tk_GetUid(str)); + + if (tkfont != NULL) { + success = 1; + if (Tk_FontType(tkfont) == TK_FONT_COMPOUND) { + aName = TkpGetFontPropertyName(tkwin, TkpGetAsciiFontStruct(tkfont)); + kName = TkpGetFontPropertyName(tkwin, TkpGetKanjiFontStruct(tkfont)); + } else { + Tk_Font defFont = TkpGetDefaultFontByDisplay(Tk_Display(tkwin)); + if (defFont != NULL) { + if (Tk_FontType(tkfont) == TK_FONT_GENERIC && + Tk_FontType(defFont) == TK_FONT_2BYTES) { + aName = TkpGetFontPropertyName(tkwin, TkpGetFontStruct(tkfont)); + kName = TkpGetFontPropertyName(tkwin, TkpGetFontStruct(defFont)); + } else if (Tk_FontType(tkfont) == TK_FONT_2BYTES && + Tk_FontType(defFont) == TK_FONT_GENERIC) { + kName = TkpGetFontPropertyName(tkwin, TkpGetFontStruct(tkfont)); + aName = TkpGetFontPropertyName(tkwin, TkpGetFontStruct(defFont)); + } else { + /* + * Both of the fonts are same type. Better Using + * IM server's default fonts. + */ + success = 0; + } + } else { + success = 0; + } + } + Tk_FreeFont(tkfont); + } + + if (aNameRet != NULL) { + *aNameRet = aName; + } + if (kNameRet != NULL) { + *kNameRet = kName; + } + if (success == 1) { + sprintf(fontNames, "%s,%s", aName, kName); + ret = Tk_GetUid(fontNames); + } + return ret; + } + + + static Window + TkpIMGetICFocusWindow(ic) + XIC ic; + { + Window ret = None; + Window fw; + if (XGetICValues(ic, XNFocusWindow, &fw, NULL) != NULL) { + ret = None; + } else { + ret = fw; + } + return ret; + } + + + static XPoint * + TkpIMSendSpotLocation(ic, spot) + XIC ic; + XPoint *spot; + { + XPoint *ret = spot; + XVaNestedList list; + list = XVaCreateNestedList(0, XNSpotLocation, spot, NULL); + if (XSetICValues(ic, XNPreeditAttributes, list, NULL) != NULL) { + ret = NULL; + } + XFree(list); + return ret; + } + + + static XPoint * + TkpIMGetSpotLocation(ic, spot) + XIC ic; + XPoint *spot; + { + XPoint *ret; + XVaNestedList list = XVaCreateNestedList(0, XNSpotLocation, &ret, NULL); + if (XGetICValues(ic, XNPreeditAttributes, list, NULL) != NULL) { + return NULL; + } else { + *spot = *ret; + XFree(ret); + return spot; + } + } + + + static XRectangle * + TkpIMSendArea(ic, attr, rect) + XIC ic; + char *attr; + XRectangle *rect; + { + XRectangle *ret = rect; + XVaNestedList list; + list = XVaCreateNestedList(0, XNArea, rect, NULL); + if (XSetICValues(ic, attr, list, NULL) != NULL) { + ret = NULL; + } + XFree(list); + return ret; + } + + + static XFontSet + TkpIMSendFontSet(ic, attr, fontset) + XIC ic; + char *attr; + XFontSet fontset; + { + XFontSet ret = fontset; + XVaNestedList fList = XVaCreateNestedList(0, XNFontSet, fontset, NULL); + if (XSetICValues(ic, attr, fList, NULL) != NULL) { + ret = NULL; + } + XFree(fList); + return ret; + } + + + static int + TkpIMSendColor(ic, fg, bg, cmap) + XIC ic; + unsigned long fg; + unsigned long bg; + Colormap cmap; + { + int ret = 1; + unsigned long fgVal = fg; + unsigned long bgVal = bg; + + XVaNestedList peList = XVaCreateNestedList(0, XNColormap, cmap, XNForeground, fgVal, + XNBackground, bgVal, NULL); + if (XSetICValues(ic, + XNPreeditAttributes, peList, + XNStatusAttributes, peList, + NULL) != NULL) { + ret = 0; + } + XFree(peList); + return ret; + } + + + static TkWindow * + TkpIMGetPreferredArea(ic, winPtr) + XIC ic; + TkWindow *winPtr; + { + TkWindow *ret = NULL; + if ((winPtr->icAttr->styleVal & XIMStatusArea) && + (winPtr->inputContext != NULL) && + (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_AREANEEDED))) { + + XRectangle area, *pArea; + XVaNestedList list; + + area.x = area.y = area.height = area.width = 0; + + list = XVaCreateNestedList(0, XNAreaNeeded, &area, NULL); + if (XSetICValues(ic, XNStatusAttributes, list, NULL) != NULL) { + winPtr->icAttr->stPrefAreaVal.x = + winPtr->icAttr->stPrefAreaVal.y = + winPtr->icAttr->stPrefAreaVal.width = + winPtr->icAttr->stPrefAreaVal.height = 0; + return ret; + } + XFree(list); + list = XVaCreateNestedList(0, XNAreaNeeded, &pArea, NULL); + if (XGetICValues(ic, XNStatusAttributes, list, NULL) != NULL) { + winPtr->icAttr->stPrefAreaVal.x = + winPtr->icAttr->stPrefAreaVal.y = + winPtr->icAttr->stPrefAreaVal.width = + winPtr->icAttr->stPrefAreaVal.height = 0; + } else { + winPtr->icAttr->stPrefAreaVal.x = pArea->x; + winPtr->icAttr->stPrefAreaVal.y = pArea->y; + winPtr->icAttr->stPrefAreaVal.width = pArea->width; + winPtr->icAttr->stPrefAreaVal.height = pArea->height; + XFree(pArea); + ret = winPtr; + } + XFree(list); + } + return ret; + } + + + static char *imOptionStrings[] = { + "-status", + "-supportedStyle", + "-style", + "-spot", + "-preeditArea", + "-statusArea", + "-preferredStatusArea", + "-font", + "-foreground", + "-background", + "-callback", + NULL + }; + + typedef enum { + IM_STATUS = 0, + IM_SUPPORTEDSTYLE, + IM_STYLE, + IM_SPOT, + IM_PREEDITAREA, + IM_STATUSAREA, + IM_PREFERREDSTATUSAREA, + IM_FONT, + IM_FOREGROUND, + IM_BACKGROUND, + IM_CALLBACK + } imOptions; + + + #define isNotNULL(A) (((icAttr->A) != NULL) ? (icAttr->A) : "{}") + #define isNotLISTNULL(A) (((icAttr->A) != NULL) ? (icAttr->A) : "") + + static void + DumpICAttribute(interp, winPtr) + Tcl_Interp *interp; + TkWindow *winPtr; + { + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + TkpICAttribute *icAttr = winPtr->icAttr; + int i; + char buf[4096]; + int len = 0; + #define WRITEIT(X, Y) \ + sprintf(buf + len, ((Y == 1) ? "{%s} " : "%s "), (X)); \ + len = strlen(buf); + int n = sizeof(imOptionStrings) / sizeof(char *) -1; + + for (i = 0; i < n; i++) { + + sprintf(buf + len, "%s ", imOptionStrings[i]); + len = strlen(buf); + + switch ((imOptions)i) { + + case IM_STATUS: { + if (winPtr->inputContext != NULL && + (winPtr->flags & TK_CHECKED_IC)) { + sprintf(buf + len, "started "); + len += 8; + } else { + sprintf(buf + len, "never "); + len += 6; + } + break; + } + + case IM_SUPPORTEDSTYLE: { + char buf2[1024]; + char *style = NULL; + int len2 = 0; + int j; + if (winPtr->dispPtr->imSupportedStyle == NULL) { + sprintf(buf + len, "{} "); + len += 3; + } else { + for (j = 0; j < winPtr->dispPtr->imSupportedStyle->count_styles; j++) { + style = GetStyleStringByStyleValue(winPtr->dispPtr->imSupportedStyle->supported_styles[j]); + sprintf(buf2 + len2, "{%s} ", (style != NULL) ? style : ""); + len2 = strlen(buf2); + } + if (buf2[len2 - 1] == ' ') { + buf2[len2 - 1] = 0; + } else { + buf2[len2] = 0; + } + sprintf(buf + len, "{%s} ", buf2); + len = strlen(buf); + } + break; + } + + case IM_STYLE: { + WRITEIT(isNotLISTNULL(style), 1); + break; + } + + case IM_SPOT: { + if ((icAttr->styleVal & XIMPreeditPosition) && + (winPtr->inputContext != NULL) && + (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_SPOT))) { + char spBuf[1024]; + XPoint spot; + if (TkpIMGetSpotLocation(winPtr->inputContext, &spot) == &spot) { + sprintf(spBuf, "%d %d", spot.x, spot.y); + sprintf(buf + len, "{%s} ", spBuf); + len = strlen(buf); + } else { + WRITEIT(isNotLISTNULL(spot), 1); + } + } else { + WRITEIT(isNotLISTNULL(spot), 1); + } + break; + } + + case IM_PREEDITAREA: { + WRITEIT(isNotLISTNULL(peArea), 1); + break; + } + + case IM_STATUSAREA: { + WRITEIT(isNotLISTNULL(stArea), 1); + break; + } + + case IM_PREFERREDSTATUSAREA: { + if (TkpIMGetPreferredArea(winPtr->inputContext, winPtr) != winPtr) { + sprintf(buf + len, "{} "); + } else { + sprintf(buf + len, "{%d %d %d %d} ", + icAttr->stPrefAreaVal.x, + icAttr->stPrefAreaVal.y, + icAttr->stPrefAreaVal.width, + icAttr->stPrefAreaVal.height); + } + len = strlen(buf); + break; + } + + case IM_FONT: { + WRITEIT(isNotNULL(font), 0); + break; + } + + case IM_FOREGROUND: { + WRITEIT(isNotNULL(fg), 0); + break; + } + + case IM_BACKGROUND: { + WRITEIT(isNotNULL(bg), 0); + break; + } + + case IM_CALLBACK: { + WRITEIT(isNotNULL(callbackCmd), 0); + break; + } + } + } + buf[len] = 0; + + Tcl_AppendStringsToObj(resultPtr, buf, NULL); + #undef WRITEIT + #undef isNotNULL + #undef isNotLISTNULL + } + + + #define isNotNULL(A) (((icAttr->A) != NULL) ? (icAttr->A) : NULL) + static int + ConfigGetICAttribute(interp, winPtr, objc, objv) + Tcl_Interp *interp; + TkWindow *winPtr; + int objc; + Tcl_Obj *CONST objv[]; + { + char *string = NULL; + char buf[1024]; + int index; + TkpICAttribute *icAttr = winPtr->icAttr; + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + + if (Tcl_GetIndexFromObj(interp, objv[0], imOptionStrings, "option", 0, &index) + != TCL_OK) { + return TCL_ERROR; + } + + switch ((imOptions)index) { + + case IM_STATUS: { + if (winPtr->inputContext != NULL && + (winPtr->flags & TK_CHECKED_IC)) { + string = "started"; + } else { + string = "never"; + } + break; + } + + case IM_SUPPORTEDSTYLE: { + int len = 0; + int j; + if (winPtr->dispPtr->imSupportedStyle == NULL) { + string = ""; + } else { + for (j = 0; j < winPtr->dispPtr->imSupportedStyle->count_styles; j++) { + sprintf(buf + len, "{%s} ", + GetStyleStringByStyleValue(winPtr->dispPtr->imSupportedStyle->supported_styles[j])); + len = strlen(buf); + } + buf[len] = 0; + string = buf; + } + break; + } + + case IM_STYLE: { + string = isNotNULL(style); + break; + } + + case IM_SPOT: { + if ((icAttr->styleVal & XIMPreeditPosition) && + (winPtr->inputContext != NULL) && + (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_SPOT))) { + XPoint spot; + if (TkpIMGetSpotLocation(winPtr->inputContext, &spot) == &spot) { + sprintf(buf, "%d %d", spot.x, spot.y); + string = buf; + } else { + string = isNotNULL(spot); + } + } else { + string = isNotNULL(spot); + } + break; + } + + case IM_PREEDITAREA: { + string = isNotNULL(peArea); + break; + } + + case IM_STATUSAREA: { + string = isNotNULL(stArea); + break; + } + + case IM_PREFERREDSTATUSAREA: { + if (TkpIMGetPreferredArea(winPtr->inputContext, winPtr) != winPtr) { + string = NULL; + } else { + sprintf(buf, "%d %d %d %d", + icAttr->stPrefAreaVal.x, + icAttr->stPrefAreaVal.y, + icAttr->stPrefAreaVal.width, + icAttr->stPrefAreaVal.height); + string = buf; + } + break; + } + + case IM_FONT: { + string = isNotNULL(font); + break; + } + + case IM_FOREGROUND: { + string = isNotNULL(fg); + break; + } + + case IM_BACKGROUND: { + string = isNotNULL(bg); + break; + } + + case IM_CALLBACK: { + string = isNotNULL(callbackCmd); + break; + } + } + + if (string != NULL) { + Tcl_AppendStringsToObj(resultPtr, string, NULL); + } + return TCL_OK; + } + #undef isNotNULL + + + static int + ConfigSetICAttribute(interp, winPtr, objc, objv, force) + Tcl_Interp *interp; + TkWindow *winPtr; + int objc; + Tcl_Obj *CONST objv[]; + int force; + { + int i; + int index; + char *string; + TkpICAttribute *icAttr = winPtr->icAttr; + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + int lObjc; + Tcl_Obj **lObjv; + int oIdx; + Tk_Uid newVal; + + if (objc & 1) { + string = Tcl_GetStringFromObj(objv[objc - 1], NULL); + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "missing value for \"", + string, "\" option", (char *) NULL); + return TCL_ERROR; + } + + icAttr->isChanged = IM_NOTHING_CHANGE; + + for (i = 0; i < objc; i += 2) { + if (Tcl_GetIndexFromObj(interp, objv[i], imOptionStrings, "option", 0, &index) + != TCL_OK) { + return TCL_ERROR; + } + oIdx = i + 1; + string = Tcl_GetStringFromObj(objv[oIdx], NULL); + newVal = Tk_GetUid(string); + + switch ((imOptions)index) { + + case IM_STATUS: + case IM_SUPPORTEDSTYLE: { + break; + } + + case IM_STYLE: { + if (Tcl_ListObjGetElements(interp, objv[oIdx], &lObjc, &lObjv) != TCL_OK) { + return TCL_ERROR; + } + if (lObjc < 2) { + Tcl_AppendStringsToObj(resultPtr, "style must be {preeditSpec statusSpec}", NULL); + return TCL_ERROR; + } + if (newVal != icAttr->style || icAttr->style == NULL) { + XIMStyle preedit = (XIMStyle)0L; + XIMStyle status = (XIMStyle)0L; + char *pStyle = NULL; + char *sStyle = NULL; + int j; + int match = 0; + + pStyle = Tcl_GetStringFromObj(lObjv[0], NULL); + sStyle = Tcl_GetStringFromObj(lObjv[1], NULL); + preedit = GetStyleValueByStyleString(pStyle); + if (preedit == (XIMStyle)0L) { + Tcl_AppendStringsToObj(resultPtr, "invalid style \"", pStyle, "\".", NULL); + return TCL_ERROR; + } + status = GetStyleValueByStyleString(sStyle); + if (status == (XIMStyle)0L) { + Tcl_AppendStringsToObj(resultPtr, "invalid style \"", sStyle, "\".", NULL); + return TCL_ERROR; + } + + /* Check the value is in the style list. */ + for (j = 0; j < winPtr->dispPtr->imSupportedStyle->count_styles; j++) { + if ((preedit|status) == winPtr->dispPtr->imSupportedStyle->supported_styles[j]) { + match = 1; + break; + } + } + if (match == 0) { + Tcl_AppendStringsToObj(resultPtr, "style \"", newVal, "\" is not supported by the input method server.", NULL); + return TCL_ERROR; + } + icAttr->styleVal = preedit|status; + icAttr->style = newVal; + icAttr->isChanged |= IM_STYLE_CHANGE; + } + break; + } + + case IM_SPOT: { + if (Tcl_ListObjGetElements(interp, objv[oIdx], &lObjc, &lObjv) != TCL_OK) { + return TCL_ERROR; + } + if (lObjc != 2) { + Tcl_AppendStringsToObj(resultPtr, "spot must be {x y}.", NULL); + return TCL_ERROR; + } + if (newVal != icAttr->spot || icAttr->spot == NULL || force) { + int x, y; + icAttr->spot = newVal; + if (Tcl_GetIntFromObj(interp, lObjv[0], &x) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[1], &y) != TCL_OK) { + return TCL_ERROR; + } + icAttr->spotVal.x = x; + icAttr->spotVal.y = y; + icAttr->isChanged |= IM_SPOT_CHANGE; + } + break; + } + + case IM_PREEDITAREA: { + if (Tcl_ListObjGetElements(interp, objv[oIdx], &lObjc, &lObjv) != TCL_OK) { + return TCL_ERROR; + } + if (lObjc != 4) { + Tcl_AppendStringsToObj(resultPtr, "area must be {x y w h}.", NULL); + return TCL_ERROR; + } + if (newVal != icAttr->peArea || icAttr->peArea == NULL || force) { + int x, y, w, h; + icAttr->peArea = newVal; + if (Tcl_GetIntFromObj(interp, lObjv[0], &x) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[1], &y) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[2], &w) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[3], &h) != TCL_OK) { + return TCL_ERROR; + } + icAttr->peAreaVal.x = x; + icAttr->peAreaVal.y = y; + icAttr->peAreaVal.width = w; + icAttr->peAreaVal.height = h; + icAttr->isChanged |= IM_PREEDITAREA_CHANGE; + } + break; + } + + case IM_STATUSAREA: { + if (Tcl_ListObjGetElements(interp, objv[oIdx], &lObjc, &lObjv) != TCL_OK) { + return TCL_ERROR; + } + if (lObjc != 4) { + Tcl_AppendStringsToObj(resultPtr, "area must be {x y w h}.", NULL); + return TCL_ERROR; + } + if (newVal != icAttr->stArea || icAttr->stArea == NULL || force) { + int x, y, w, h; + icAttr->stArea = newVal; + if (Tcl_GetIntFromObj(interp, lObjv[0], &x) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[1], &y) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[2], &w) != TCL_OK) { + return TCL_ERROR; + } + if (Tcl_GetIntFromObj(interp, lObjv[3], &h) != TCL_OK) { + return TCL_ERROR; + } + icAttr->stAreaVal.x = x; + icAttr->stAreaVal.y = y; + icAttr->stAreaVal.width = w; + icAttr->stAreaVal.height = h; + icAttr->isChanged |= IM_STATUSAREA_CHANGE; + } + break; + } + + case IM_PREFERREDSTATUSAREA: { + break; + } + + case IM_FONT: { + #ifdef USE_XFONTSET + char **ml; + int mc; + char *ds; + #endif /* USE_XFONTSET */ + char *aName; + char *kName; + + Tk_Uid new = GetFontNames(interp, (Tk_Window)winPtr, newVal, &aName, &kName); + XFontSet nf = NULL; + + if (new == NULL) { + /* + * Just break. + */ + goto noFontFound; + } + if (new != icAttr->fontlist || icAttr->fontlist == NULL || force) { + if (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_FONT)) { + if (icAttr->fontset != NULL) { + #ifdef USE_XFONTSET + XFreeFontSet(Tk_Display(winPtr), icAttr->fontset); + #else + TkpFreeFontSet((Tk_Window)winPtr, icAttr->fontset); + #endif /* USE_XFONTSET */ + } + #ifdef USE_XFONTSET + nf = XCreateFontSet(Tk_Display(winPtr), new, &ml, &mc, &ds); + if (mc > 0) { + XFreeStringLsit(ml); + } + #else + nf = TkpCreateFontSet((Tk_Window)winPtr, new, aName, kName); + #endif /* USE_XFONTSET */ + if (nf == NULL) { + icAttr->font = NULL; + icAttr->fontlist = NULL; + icAttr->fontset = NULL; + Tcl_AppendStringsToObj(resultPtr, "Can't create fontset \"", newVal, + "\" -> \"", new, "\".", NULL); + return TCL_ERROR; + } + } + icAttr->font = newVal; + icAttr->fontlist = new; + icAttr->fontset = nf; + icAttr->isChanged |= IM_FONT_CHANGE; + } + noFontFound: + break; + } + + case IM_FOREGROUND: { + if (newVal != icAttr->fg || icAttr->fg == NULL || force) { + XColor *c = Tk_GetColor(interp, (Tk_Window)winPtr, newVal); + if (c == NULL) { + Tcl_AppendStringsToObj(resultPtr, "Can't find color \"", string, + "\".", NULL); + return TCL_ERROR; + } + icAttr->fg = newVal; + icAttr->fgVal = c->pixel; + icAttr->isChanged |= IM_COLOR_CHANGE; + } + break; + } + + case IM_BACKGROUND: { + if (newVal != icAttr->bg || icAttr->bg == NULL || force) { + XColor *c = Tk_GetColor(interp, (Tk_Window)winPtr, newVal); + if (c == NULL) { + Tcl_AppendStringsToObj(resultPtr, "Can't find color \"", string, + "\".", NULL); + return TCL_ERROR; + } + icAttr->bg = newVal; + icAttr->bgVal = c->pixel; + icAttr->isChanged |= IM_COLOR_CHANGE; + } + break; + } + + case IM_CALLBACK: { + icAttr->callbackCmd = newVal; + break; + } + } + } + return TCL_OK; + } + + + static XIC + TkpCreateIC(winPtr) + TkWindow *winPtr; + { + XIC ret = NULL; + + XIMStyle style = winPtr->icAttr->styleVal; + XIMStyle preedit = winPtr->icAttr->styleVal & TkIMPreeditMask; + XIMStyle status = winPtr->icAttr->styleVal & TkIMStatusMask; + + XVaNestedList pList = NULL; + XVaNestedList sList = NULL; + XPoint spot; + XRectangle pArea; + XRectangle sArea; + XFontSet fontset = winPtr->icAttr->fontset; + int doFont = (fontset == NULL) ? 0 : ( (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_FONT)) ? 1 : 0 ); + int doSpot = 0; + int canArea = (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_AREA)) ? 1 : 0; + int doPArea = 0; + int doSArea = 0; + + (VOID)memset((VOID *)&pArea, 0, sizeof(XRectangle)); + (VOID)memset((VOID *)&sArea, 0, sizeof(XRectangle)); + + winPtr->icAttr->doPreedit = 0; + winPtr->icAttr->doStatus = 0; + + switch (preedit) { + + case XIMPreeditArea: { + if (canArea) { + pArea.x = winPtr->icAttr->peAreaVal.x; + pArea.y = winPtr->icAttr->peAreaVal.y; + pArea.width = (winPtr->icAttr->peAreaVal.width != 0) ? + winPtr->icAttr->peAreaVal.width : winPtr->reqWidth; + pArea.height = (winPtr->icAttr->peAreaVal.height != 0) ? + winPtr->icAttr->peAreaVal.height : winPtr->reqHeight; + } + if (doFont && canArea) { + pList = XVaCreateNestedList(0, XNArea, &pArea, XNFontSet, fontset, NULL); + } else if (doFont && !canArea) { + pList = XVaCreateNestedList(0, XNFontSet, fontset, NULL); + } else if (!doFont && canArea) { + pList = XVaCreateNestedList(0, XNArea, &pArea, NULL); + } + doPArea = 1; + winPtr->icAttr->doPreedit = 1; + break; + } + + case XIMPreeditCallbacks: { + #ifdef TK_USE_ON_THE_SPOT + doPArea = 0; + pList = GenPreeditCallbackVaList(winPtr); + winPtr->icAttr->doPreedit = 0; + #else + /* + * Fall back to PreeditNothing + */ + goto fallbackToPreeditNothing; + #endif /* TK_USE_ON_THE_SPOT */ + break; + } + + case XIMPreeditPosition: { + spot.x = winPtr->icAttr->spotVal.x; + spot.y = winPtr->icAttr->spotVal.y; + if (doFont) { + pList = XVaCreateNestedList(0, XNSpotLocation, &spot, XNFontSet, fontset, NULL); + } else { + pList = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL); + } + doSpot = (imSupportAttr(winPtr->dispPtr, IM_SUPPORT_SPOT)) ? 1 : 0; + winPtr->icAttr->doPreedit = 1; + break; + } + + case XIMPreeditNothing: + case XIMPreeditNone: { + #ifndef TK_USE_ON_THE_SPOT + fallbackToPreeditNothing: + #endif /* !TK_USE_ON_THE_SPOT */ + /* + * Maybe this is useless.. + */ + if (doFont) { + pList = XVaCreateNestedList(0, XNFontSet, fontset, NULL); + } + winPtr->icAttr->doPreedit = 0; + break; + } + } + + switch (status) { + + case XIMStatusArea: { + if (canArea) { + sArea.x = winPtr->icAttr->stAreaVal.x; + sArea.y = winPtr->icAttr->stAreaVal.y; + sArea.width = (winPtr->icAttr->stAreaVal.width != 0) ? + winPtr->icAttr->stAreaVal.width : winPtr->reqWidth; + sArea.height = (winPtr->icAttr->stAreaVal.height != 0) ? + winPtr->icAttr->stAreaVal.height : winPtr->reqHeight; + } + if (doFont && canArea) { + sList = XVaCreateNestedList(0, XNArea, &sArea, XNFontSet, fontset, NULL); + } else if (doFont && !canArea) { + sList = XVaCreateNestedList(0, XNFontSet, fontset, NULL); + } else if (!doFont && canArea) { + sList = XVaCreateNestedList(0, XNArea, &sArea, NULL); + } + doSArea = 1; + winPtr->icAttr->doStatus = 1; + break; + } + + case XIMStatusCallbacks: { + #ifdef TK_USE_ON_THE_SPOT + sList = GenStatusCallbackVaList(winPtr); + winPtr->icAttr->doStatus = 0; + #else + /* + * Fall back to StatusNothing + */ + goto fallbackToStatusNothing; + #endif /* TK_USE_ON_THE_SPOT */ + break; + } + + case XIMStatusNothing: + case XIMStatusNone: { + #ifndef TK_USE_ON_THE_SPOT + fallbackToStatusNothing: + #endif /* !TK_USE_ON_THE_SPOT */ + if (doFont) { + sList = XVaCreateNestedList(0, XNFontSet, fontset, NULL); + } + winPtr->icAttr->doStatus = 0; + break; + } + } + + #ifdef XIM_DEBUG + fprintf(stderr, "debugIC: creating IC with '%s%s%s%s%s'\n", + (doFont) ? "font " : "", + (doSpot) ? "spot " : "", + (canArea) ? "area " : "", + (doPArea) ? "preeditArea " : "", + (doSArea) ? "statusArea " : ""); + #endif /* XIM_DEBUG */ + + /* + * OK, roll'em. + */ + if (pList != NULL && sList != NULL) { + ret = XCreateIC(winPtr->dispPtr->inputMethod, + XNInputStyle, style, + XNClientWindow, winPtr->window, + XNFocusWindow, winPtr->window, + XNPreeditAttributes, pList, + XNStatusAttributes, sList, + NULL); + XFree(pList); + XFree(sList); + } else if (pList != NULL && sList == NULL) { + ret = XCreateIC(winPtr->dispPtr->inputMethod, + XNInputStyle, style, + XNClientWindow, winPtr->window, + XNFocusWindow, winPtr->window, + XNPreeditAttributes, pList, + NULL); + XFree(pList); + } else if (pList == NULL && sList != NULL) { + ret = XCreateIC(winPtr->dispPtr->inputMethod, + XNInputStyle, style, + XNClientWindow, winPtr->window, + XNFocusWindow, winPtr->window, + XNStatusAttributes, sList, + NULL); + XFree(sList); + } else { + ret = XCreateIC(winPtr->dispPtr->inputMethod, + XNInputStyle, style, + XNClientWindow, winPtr->window, + XNFocusWindow, winPtr->window, + NULL); + } + + if (ret != NULL) { + #if 0 + /* + * Checking the input style. This also avoid freeze. + */ + XIMStyle getStyle; + if (XGetICValues(ret, XNInputStyle, &getStyle, NULL) == NULL) { + if (style != getStyle) { + /* + * What's up ? + */ + winPtr->inputContext = ret; + TkpDestroyIC(winPtr); + ret = NULL; + goto CreateFail; + } + } + #endif + #if 0 + fprintf(stderr, "debugIC: created.\n"); + { + unsigned long eMask = 0; + fprintf(stderr, "debugIC: get event mask...\n"); + if (XGetICValues(ret, XNFilterEvents, &eMask, NULL) != NULL) { + fprintf(stderr, "debugIC: can't get event mask\n"); + } + fprintf(stderr, "debugIC: event mask 0x%08x\n", eMask); + } + #endif + if (doSArea && canArea) { + /* + * Get the IM's preferred status area. + */ + XRectangle area; + if (TkpIMGetPreferredArea(ret, winPtr) == winPtr) { + area.width = winPtr->icAttr->stPrefAreaVal.width; + area.height = winPtr->icAttr->stPrefAreaVal.height; + if (doSpot) { + area.x = spot.x; + area.y = spot.y; + } else if (doPArea && canArea) { + area.x = pArea.x; + area.y = pArea.y; + } else { + area.x = 0; + area.y = 0; + } + TkpIMSendArea(ret, XNStatusAttributes, &area); + } + } + + /* + * Register a generic event handler for Input focus. + */ + TkpCreateIMGenericHandler((Tk_Window)winPtr); + + winPtr->icAttr->isChanged &= ~(IM_STYLE_CHANGE); + if (doFont) { + winPtr->icAttr->isChanged &= ~(IM_FONT_CHANGE); + } + if (doSpot) { + winPtr->icAttr->isChanged &= ~(IM_SPOT_CHANGE); + } + if (doPArea) { + winPtr->icAttr->isChanged &= ~(IM_PREEDITAREA_CHANGE); + } + if (doSArea) { + winPtr->icAttr->isChanged &= ~(IM_STATUSAREA_CHANGE); + } + winPtr->flags |= TK_CHECKED_IC; + winPtr->inputContext = ret; + if (winPtr->icAttr->styleVal != style) { + winPtr->icAttr->style = Tk_GetUid(GetStyleStringByStyleValue(style)); + winPtr->icAttr->styleVal = style; + } + } else { + CreateFail: + winPtr->flags &= ~(TK_CHECKED_IC); + winPtr->inputContext = NULL; + } + winPtr->icAttr->icState = IC_NEVER_USED; + return ret; + } + + + static void + TkpDestroyIC(winPtr) + TkWindow *winPtr; + { + if (winPtr->inputContext == winPtr->dispPtr->lastFocusedIC) { + winPtr->dispPtr->lastFocusedIC = None; + } + SetICState(winPtr->icAttr, IC_DESTROYED); + XDestroyIC(winPtr->inputContext); + winPtr->flags &= ~(TK_CHECKED_IC); + winPtr->inputContext = NULL; + SetICState(winPtr->icAttr, IC_NEVER_USED); + } + + + static int + TkpConfigIC(interp, winPtr) + Tcl_Interp *interp; + TkWindow *winPtr; + { + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + int ret = TCL_ERROR; + + #define isAttrChanged(X) ( winPtr->icAttr->isChanged & (X) ) + #define isSupported(X) ( imSupportAttr(winPtr->dispPtr, (X)) ) + + if (!(winPtr->flags & TK_CHECKED_IC) || + (winPtr->inputContext == NULL) || + isAttrChanged(IM_STYLE_CHANGE)) { + if (isAttrChanged(IM_STYLE_CHANGE)) { + if (winPtr->inputContext != NULL) { + if (!(IsSetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW))) { + TkpDestroyIC(winPtr); + } else { + Tcl_AppendStringsToObj(resultPtr, "can't change style right now.", NULL); + return TCL_ERROR; + } + } + winPtr->icAttr->isChanged &= ~(IM_STYLE_CHANGE); + } + if (winPtr->icAttr->styleVal != (XIMStyle)0L) { + if (TkpCreateIC(winPtr) == NULL) { + Tcl_AppendStringsToObj(resultPtr, "can't create IC.", NULL); + return TCL_ERROR; + } + } + } + + if (winPtr->inputContext == NULL) { + Tcl_AppendStringsToObj(resultPtr, "IC is not created.", NULL); + return TCL_ERROR; + } + + #ifdef XIM_DEBUG + { + fprintf(stderr, "debugIC: Changing attr of IC with '%s%s%s%s%s'\n", + (isAttrChanged(IM_PREEDITAREA_CHANGE) ? "preedit " : ""), + (isAttrChanged(IM_STATUSAREA_CHANGE) ? "status " : ""), + (isAttrChanged(IM_SPOT_CHANGE) ? "spot " : ""), + (isAttrChanged(IM_FONT_CHANGE) ? "font " : ""), + (isAttrChanged(IM_COLOR_CHANGE) ? "color " : "")); + } + #endif /* XIM_DEBUG */ + if (winPtr->icAttr->isChanged == IM_NOTHING_CHANGE) { + return TCL_OK; + } + ret = TkpIMSendAttribute(interp, winPtr); + #ifdef XIM_DEBUG + { + fprintf(stderr, "debugIC: pending change '%s%s%s%s%s'\n", + (isAttrChanged(IM_PREEDITAREA_CHANGE) ? "preedit " : ""), + (isAttrChanged(IM_STATUSAREA_CHANGE) ? "status " : ""), + (isAttrChanged(IM_SPOT_CHANGE) ? "spot " : ""), + (isAttrChanged(IM_FONT_CHANGE) ? "font " : ""), + (isAttrChanged(IM_COLOR_CHANGE) ? "color " : "")); + } + #endif /* XIM_DEBUG */ + winPtr->icAttr->isChanged = IM_NOTHING_CHANGE; + SetICState(winPtr->icAttr, IC_USED_AT_LEAST_ONETIME); + return ret; + #undef isAttrChanged + #undef isSupported + } + + + static int + GenerateAttrVaList(winPtr, peListPtr, stListPtr) + TkWindow *winPtr; + XVaNestedList *peListPtr; + XVaNestedList *stListPtr; + { + #define isSupported(X) ( imSupportAttr(winPtr->dispPtr, (X)) ) + #define isAttrChanged(X) ( winPtr->icAttr->isChanged & (X) ) + #define makeMask(X, Y) ((isSupported(X) && isAttrChanged(Y)) ? (Y) : 0L) + + int canPEArea = (isSupported(IM_SUPPORT_PREEDITAREA) && + (peListPtr != NULL) && + winPtr->icAttr->doPreedit == 1) ? 1 : 0; + int canSTArea = (isSupported(IM_SUPPORT_STATUSAREA) && + (stListPtr != NULL) && + winPtr->icAttr->doStatus == 1) ? 1 : 0; + + int realPEAttr = makeMask(IM_SUPPORT_PREEDITAREA, IM_PREEDITAREA_CHANGE) | + makeMask(IM_SUPPORT_SPOT, IM_SPOT_CHANGE) | + makeMask(IM_SUPPORT_FONT, IM_FONT_CHANGE) | + makeMask(IM_SUPPORT_COLOR, IM_COLOR_CHANGE); + + int realSTAttr = makeMask(IM_SUPPORT_STATUSAREA, IM_STATUSAREA_CHANGE) | + makeMask(IM_SUPPORT_FONT, IM_FONT_CHANGE) | + makeMask(IM_SUPPORT_COLOR, IM_COLOR_CHANGE); + + int realChanged = IM_NOTHING_CHANGE; + + XVaNestedList pList = NULL; + XVaNestedList sList = NULL; + + if (winPtr->icAttr->fontset == NULL) { + realPEAttr &= ~(IM_FONT_CHANGE); + realSTAttr &= ~(IM_FONT_CHANGE); + } + realChanged = realPEAttr | realSTAttr; + + #define icOpt(Y) (winPtr->icAttr->Y) + + #define PEAreaOpt XNArea, &(icOpt(peAreaVal)) + #define STAreaOpt XNArea, &(icOpt(stAreaVal)) + #define spotOpt XNSpotLocation, &(icOpt(spotVal)) + #define fontOpt XNFontSet, icOpt(fontset) + #define colorOpt XNColormap, winPtr->atts.colormap, \ + XNForeground, icOpt(fgVal), \ + XNBackground, icOpt(bgVal) + + if (canPEArea == 1) { + switch (realPEAttr) { + case (IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, spotOpt, NULL); break; + } + case (IM_COLOR_CHANGE): { + pList = XVaCreateNestedList(0, colorOpt, NULL); break; + } + case (IM_COLOR_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, colorOpt, spotOpt, NULL); break; + } + case (IM_FONT_CHANGE): { + pList = XVaCreateNestedList(0, fontOpt, NULL); break; + } + case (IM_FONT_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, fontOpt, spotOpt, NULL); break; + } + case (IM_FONT_CHANGE|IM_COLOR_CHANGE): { + pList = XVaCreateNestedList(0, fontOpt, colorOpt, NULL); break; + } + case (IM_FONT_CHANGE|IM_COLOR_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, fontOpt, colorOpt, spotOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, spotOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_COLOR_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, colorOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_COLOR_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, colorOpt, spotOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_FONT_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, fontOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_FONT_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, fontOpt, spotOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_FONT_CHANGE|IM_COLOR_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, fontOpt, colorOpt, NULL); break; + } + case (IM_PREEDITAREA_CHANGE|IM_FONT_CHANGE|IM_COLOR_CHANGE|IM_SPOT_CHANGE): { + pList = XVaCreateNestedList(0, PEAreaOpt, fontOpt, colorOpt, spotOpt, NULL); break; + } + } + *peListPtr = pList; + } + if (canSTArea == 1) { + switch (realSTAttr) { + case (IM_COLOR_CHANGE): { + sList = XVaCreateNestedList(0, colorOpt, NULL); break; + } + case (IM_FONT_CHANGE): { + sList = XVaCreateNestedList(0, fontOpt, NULL); break; + } + case (IM_FONT_CHANGE|IM_COLOR_CHANGE): { + sList = XVaCreateNestedList(0, fontOpt, colorOpt, NULL); break; + } + case (IM_STATUSAREA_CHANGE): { + sList = XVaCreateNestedList(0, STAreaOpt, NULL); break; + } + case (IM_STATUSAREA_CHANGE|IM_COLOR_CHANGE): { + sList = XVaCreateNestedList(0, STAreaOpt, colorOpt, NULL); break; + } + case (IM_STATUSAREA_CHANGE|IM_FONT_CHANGE): { + sList = XVaCreateNestedList(0, STAreaOpt, fontOpt, NULL); break; + } + case (IM_STATUSAREA_CHANGE|IM_FONT_CHANGE|IM_COLOR_CHANGE): { + sList = XVaCreateNestedList(0, STAreaOpt, fontOpt, colorOpt, NULL); break; + } + } + *stListPtr = sList; + } + + return realChanged; + #undef isAttrChanged + #undef isSupported + #undef makeMask + #undef icOpt + #undef PEAreaOpt + #undef STAreaOpt + #undef spotOpt + #undef fontOpt + #undef colorOpt + } + + + static int + TkpIMSendAttribute(interp, winPtr) + Tcl_Interp *interp; + TkWindow *winPtr; + { + XVaNestedList pList = NULL; + XVaNestedList sList = NULL; + char *result = NULL; + + int change = GenerateAttrVaList(winPtr, &pList, &sList); + if (pList != NULL && sList != NULL) { + result = XSetICValues(winPtr->inputContext, + XNPreeditAttributes, pList, + XNStatusAttributes, sList, + NULL); + if (result != NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "Can't set XIC attributes \"", + XNPreeditAttributes, + XNStatusAttributes, + "\"", NULL); + } + } else if (pList != NULL && sList == NULL) { + result = XSetICValues(winPtr->inputContext, + XNPreeditAttributes, pList, + NULL); + if (result != NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "Can't set XIC attributes \"", + XNPreeditAttributes, + "\"", NULL); + } + } else if (pList == NULL && sList != NULL) { + result = XSetICValues(winPtr->inputContext, + XNStatusAttributes, sList, + NULL); + if (result != NULL) { + Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), + "Can't set XIC attributes \"", + XNStatusAttributes, + "\"", NULL); + } + } + + if (result == NULL) { + winPtr->icAttr->isChanged &= ~(change); + } + if (pList != NULL) { + XFree(pList); + } + if (sList != NULL) { + XFree(sList); + } + return (result == NULL) ? TCL_OK : TCL_ERROR; + } + + /* + * Exported Stuff. + */ + + unsigned long + TkpGetSupportedICAttribute(icVal) + XIMValuesList *icVal; + { + unsigned short i; + unsigned long ret = IM_SUPPORT_NOTHING; + int doColor = 0; + + for (i = 0; i < icVal->count_values; i++) { + #ifdef XIM_DEBUG + fprintf(stderr, "debug: IM supports IC attr %d '%s'\n", i, icVal->supported_values[i]); + #endif /* XIM_DEBUG */ + if (strcmp(icVal->supported_values[i], XNPreeditAttributes) == 0) { + ret |= IM_SUPPORT_PREEDITAREA; + } else if (strcmp(icVal->supported_values[i], XNStatusAttributes) == 0) { + ret |= IM_SUPPORT_STATUSAREA; + } else if (strcmp(icVal->supported_values[i], XNArea) == 0) { + ret |= IM_SUPPORT_AREA; + } else if (strcmp(icVal->supported_values[i], XNAreaNeeded) == 0) { + ret |= IM_SUPPORT_AREANEEDED; + } else if (strcmp(icVal->supported_values[i], XNSpotLocation) == 0) { + ret |= IM_SUPPORT_SPOT; + } else if (strcmp(icVal->supported_values[i], XNFontSet) == 0) { + ret |= IM_SUPPORT_FONT; + } else if ((strcmp(icVal->supported_values[i], XNColormap) == 0) || + (strcmp(icVal->supported_values[i], XNForeground) == 0) || + (strcmp(icVal->supported_values[i], XNBackground) == 0)) { + doColor++; + if (doColor >= 3) { + ret |= IM_SUPPORT_COLOR; + } + } + } + #ifdef XIM_DEBUG + fprintf(stderr, "debug: IM support attr 0x%08lx\n", ret); + #endif /* XIM_DEBUG */ + return ret; + } + + + TkpICAttribute * + TkpAllocICAttribute(tkwin) + Tk_Window tkwin; + { + TkpICAttribute *ret = (TkpICAttribute *)ckalloc(sizeof(TkpICAttribute)); + memset((VOID *)ret, 0, sizeof(TkpICAttribute)); + return ret; + } + + + void + TkpDeleteICAttribute(tkwin, attr) + Tk_Window tkwin; + TkpICAttribute *attr; + { + if (attr->fontset != NULL) { + #ifdef USE_XFONTSET + XFreeFontSet(Tk_Display(tkwin), attr->fontset); + #else + TkpFreeFontSet(tkwin, attr->fontset); + #endif /* USE_XFONTSET */ + } + ckfree((char *)attr); + } + + + void + TkpCreateIMGenericHandler(tkwin) + Tk_Window tkwin; + { + Tk_CreateEventHandler(tkwin, FocusChangeMask|StructureNotifyMask|KeyPressMask + #if 0 + EnterWindowMask|LeaveWindowMask, + #else + , + #endif + (Tk_EventProc *)TkpIMGenericHandler, + (ClientData)tkwin); + } + + + void + TkpDeleteIMGenericHandler(tkwin) + Tk_Window tkwin; + { + Tk_DeleteEventHandler(tkwin, FocusChangeMask|StructureNotifyMask|KeyPressMask + #if 0 + EnterWindowMask|LeaveWindowMask, + #else + , + #endif + (Tk_EventProc *)TkpIMGenericHandler, + (ClientData)tkwin); + } + + + int + Tk_ImconfigureObjCmd(clientData, interp, objc, objv) + ClientData clientData; /* Main window associated with + * interpreter. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ + { + TkWindow *winPtr; + Tk_Window tkwin = (Tk_Window)clientData; + char *string; + Tcl_Obj *resultPtr = Tcl_GetObjResult(interp); + int doForce = 0; + int idx = 2; + int nObjc = objc; + + if (objc < 2) { + Tcl_WrongNumArgs(interp, 1, objv, "path ?option? ?arg? ..."); + return TCL_ERROR; + } + string = Tcl_GetStringFromObj(objv[1], NULL); + tkwin = Tk_NameToWindow(interp, string, tkwin); + if (tkwin == NULL) { + return TCL_ERROR; + } + winPtr = (TkWindow *)tkwin; + + if (winPtr->dispPtr->inputMethod == NULL) { + Tcl_AppendStringsToObj(resultPtr, "No IM server is available.", NULL); + return TCL_ERROR; + } else if (winPtr->dispPtr->imSupportedStyle == NULL) { + Tcl_AppendStringsToObj(resultPtr, "IM server doesn't support any input style.", NULL); + return TCL_ERROR; + } else if (IsSetICState(winPtr->icAttr, IC_DESTROYED) || + IsSetICState(winPtr->icAttr, IC_ASSOC_WIN_DELETED)) { + Tcl_AppendStringsToObj(resultPtr, "IC was destroyed.", NULL); + return TCL_ERROR; + } + + if (objc == 2) { + DumpICAttribute(interp, winPtr); + return TCL_OK; + } + + if (objc >= 3) { + string = Tcl_GetStringFromObj(objv[2], NULL); + if (strcmp(string, "-force") == 0) { + nObjc--; + doForce = 1; + idx++; + } + } + + if (nObjc == 3) { + return ConfigGetICAttribute(interp, winPtr, objc - idx, objv + idx); + } + + if (ConfigSetICAttribute(interp, winPtr, objc - idx, objv + idx, doForce) != TCL_OK) { + return TCL_ERROR; + } + #ifdef XIM_DEBUG + #define isAttrChanged(X) ( winPtr->icAttr->isChanged & (X) ) + { + fprintf(stderr, "debugIC: (Top) Changing attr of IC with '%s%s%s%s%s'\n", + (isAttrChanged(IM_PREEDITAREA_CHANGE) ? "preedit " : ""), + (isAttrChanged(IM_STATUSAREA_CHANGE) ? "status " : ""), + (isAttrChanged(IM_SPOT_CHANGE) ? "spot " : ""), + (isAttrChanged(IM_FONT_CHANGE) ? "font " : ""), + (isAttrChanged(IM_COLOR_CHANGE) ? "color " : "")); + } + #undef isAttrChanged + #endif /* XIM_DEBUG */ + if (winPtr->icAttr->isChanged != IM_NOTHING_CHANGE || + winPtr->inputContext == NULL) { + return TkpConfigIC(interp, winPtr); + } + return TCL_OK; + } + + + static Tcl_HashTable imBarrierTbl; + static int imBarrierInited = 0; + + + static void + imBarrierInit() + { + if (imBarrierInited == 0) { + Tcl_InitHashTable(&imBarrierTbl, TCL_ONE_WORD_KEYS); + imBarrierInited = 1; + } + } + + + static void + TkpIMSetBarrier(dpy) + Display *dpy; + { + int new = 0; + Tcl_HashEntry *imBPtr; + if (imBarrierInited == 0) { + imBarrierInit(); + } + imBPtr = Tcl_CreateHashEntry(&imBarrierTbl, (char *)dpy, &new); + if (new == 1) { + int *val = (int *)ckalloc(sizeof(int)); + *val = 1; + Tcl_SetHashValue(imBPtr, (ClientData)val); + } else { + int *val = (int *)Tcl_GetHashValue(imBPtr); + if (*val == 1) { + panic("this display is already barrier'd."); + } + *val = 1; + } + return; + } + + + static void + TkpIMUnsetBarrier(dpy) + Display *dpy; + { + Tcl_HashEntry *imBPtr = NULL; + int *val = NULL; + if (imBarrierInited == 0) { + panic("IM barrier is not initialized."); + } + imBPtr = Tcl_FindHashEntry(&imBarrierTbl, (char *)dpy); + if (imBPtr == NULL) { + panic("this display is NOT barrier'd."); + } + val = (int *)Tcl_GetHashValue(imBPtr); + if (val == NULL) { + panic("this display is NOT barrier'd (val == NULL)."); + } + if (*val == 0) { + panic("this display is NOT barrier'd (*val == 0)."); + } + *val = 0; + return; + } + + + Bool + TkpIMIsDisplayInBarrier(dpy) + Display *dpy; + { + Tcl_HashEntry *imBPtr = NULL; + int *val = NULL; + + if (imBarrierInited == 0) { + imBarrierInit(); + return False; + } + imBPtr = Tcl_FindHashEntry(&imBarrierTbl, (char *)dpy); + if (imBPtr == NULL) { + return False; + } + val = (int *)Tcl_GetHashValue(imBPtr); + if (val == NULL) { + return False; + } + if (*val == 0) { + return False; + } else { + return True; + } + } + + + #ifdef XIM_DEBUG + static char imFBBuf[4096]; + static char * + IMFeedback2Str(ximFBPtr) + XIMFeedback *ximFBPtr; + { + if (ximFBPtr == NULL) { + imFBBuf[0] = '\0'; + return imFBBuf; + } + + memset(imFBBuf, 0, 4096); + if (*ximFBPtr & XIMReverse) { + strcat(imFBBuf, "Reverse "); + } + if (*ximFBPtr & XIMUnderline) { + strcat(imFBBuf, "Underline "); + } + if (*ximFBPtr & XIMHighlight) { + strcat(imFBBuf, "Highlight "); + } + if (*ximFBPtr & XIMPrimary) { + strcat(imFBBuf, "Primary "); + } + if (*ximFBPtr & XIMSecondary) { + strcat(imFBBuf, "Secondary "); + } + if (*ximFBPtr & XIMTertiary) { + strcat(imFBBuf, "Tertiary "); + } + if (*ximFBPtr & XIMVisibleToForward) { + strcat(imFBBuf, "VisibleToForward "); + } + if (*ximFBPtr & XIMVisibleToBackword) { + strcat(imFBBuf, "VisibleToBackword "); + } + if (*ximFBPtr & XIMVisibleToCenter) { + strcat(imFBBuf, "VisibleToCenter"); + } + return imFBBuf; + } + #endif /* XIM_DEBUG */ + + static void + AppendIMFeedbackToObj(interp, ximFBPtr, objPtr) + Tcl_Interp *interp; + XIMFeedback *ximFBPtr; + Tcl_Obj *objPtr; + { + if (*ximFBPtr & XIMReverse) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("Reverse", -1)); + } + if (*ximFBPtr & XIMUnderline) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("Underline", -1)); + } + if (*ximFBPtr & XIMHighlight) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("Highlight", -1)); + } + if (*ximFBPtr & XIMPrimary) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("Primary", -1)); + } + if (*ximFBPtr & XIMSecondary) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("Secondary", -1)); + } + if (*ximFBPtr & XIMTertiary) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("Tertiary", -1)); + } + if (*ximFBPtr & XIMVisibleToForward) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("VisibleToForward", -1)); + } + if (*ximFBPtr & XIMVisibleToBackword) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("VisibleToBackward", -1)); + } + if (*ximFBPtr & XIMVisibleToCenter) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("VisibleToCenter", -1)); + } + } + + + static void + AppendXIMTextToObj(interp, text, objPtr) + Tcl_Interp *interp; + XIMText *text; + Tcl_Obj *objPtr; + { + #ifdef XIM_DEBUG + if (text == NULL) { + fprintf(stderr, "\tXIMText NULL.\n"); + } else { + fprintf(stderr, "\tencode %s len %d (real %d)", + (text->encoding_is_wchar == True) ? "wchar" : "multibytes", + text->length, strlen(text->string.multi_byte)); + if (text->encoding_is_wchar != True) { + fprintf(stderr, " '%s'", text->string.multi_byte); + } else { + fprintf(stderr, " ''"); + } + } + fprintf(stderr, " feedback '%s'\n", IMFeedback2Str(text->feedback)); + #endif /* XIM_DEBUG */ + if (text == NULL) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("", -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("", -1)); + return; + } + if (text->encoding_is_wchar != True) { + Tcl_ListObjAppendElement(interp, objPtr, + Tcl_NewStringObj(text->string.multi_byte, -1)); + } else { + /* + * Cheat. can't handle wide character. BTW, who can ? In + * general, It is impossible to determine how the wide + * character be encoded. It depends on implementation of IM + * server. I love to say "XIM sux". + */ + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("", -1)); + } + if (text->feedback != NULL && *(text->feedback) != 0L) { + Tcl_Obj *feedback = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + AppendIMFeedbackToObj(interp, text->feedback, feedback); + Tcl_IncrRefCount(feedback); + Tcl_ListObjAppendElement(interp, objPtr, feedback); + Tcl_DecrRefCount(feedback); + } else { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj("", -1)); + } + return; + } + + + #define CARET_IsInvisible 0 + #define CARET_IsPrimary 1 + #define CARET_IsSecondary 2 + #define CARET_UnknownStyle 3 + + static char *caretStyleTbl[] = { + "IsInbisible", + "IsPrimary", + "IsSecondary", + "", + NULL + }; + + #define CARET_ForwardC 0 + #define CARET_BackwardC 1 + #define CARET_ForwardW 2 + #define CARET_BackwardW 3 + #define CARET_Up 4 + #define CARET_Down 5 + #define CARET_PreviousL 6 + #define CARET_NextL 7 + #define CARET_LineStart 8 + #define CARET_LineEnd 9 + #define CARET_AbsolutePos 10 + #define CARET_DontChange 11 + #define CARET_UnknownDirection 12 + + static char *caretDirTbl[] = { + "ForwardChar", + "BackwardChar", + "ForwardWord", + "BackwardWord", + "Up", + "Down", + "PreviousLine", + "NextLine", + "LineStart", + "LineEnd", + "AbsolutePosition", + "DontChange", + "", + NULL + }; + + + static char * + IMCaretStyle2Str(style) + XIMCaretStyle style; + { + switch (style) { + case XIMIsInvisible: { + return caretStyleTbl[CARET_IsInvisible]; + break; + } + case XIMIsPrimary: { + return caretStyleTbl[CARET_IsPrimary]; + break; + } + case XIMIsSecondary: { + return caretStyleTbl[CARET_IsSecondary]; + break; + } + default: { + return caretStyleTbl[CARET_UnknownStyle]; + break; + } + } + return caretStyleTbl[CARET_UnknownStyle]; + } + + + static char * + IMCaretDirection2Str(dir) + XIMCaretDirection dir; + { + switch (dir) { + case XIMForwardChar: { + return caretDirTbl[CARET_ForwardC]; + break; + } + case XIMBackwardChar: { + return caretDirTbl[CARET_BackwardC]; + break; + } + case XIMForwardWord: { + return caretDirTbl[CARET_ForwardW]; + break; + } + case XIMBackwardWord: { + return caretDirTbl[CARET_BackwardW]; + break; + } + case XIMCaretUp: { + return caretDirTbl[CARET_Up]; + break; + } + case XIMCaretDown: { + return caretDirTbl[CARET_Down]; + break; + } + case XIMPreviousLine: { + return caretDirTbl[CARET_PreviousL]; + break; + } + case XIMNextLine: { + return caretDirTbl[CARET_NextL]; + break; + } + case XIMLineStart: { + return caretDirTbl[CARET_LineStart]; + break; + } + case XIMLineEnd: { + return caretDirTbl[CARET_LineEnd]; + break; + } + case XIMAbsolutePosition: { + return caretDirTbl[CARET_AbsolutePos]; + break; + } + case XIMDontChange: { + return caretDirTbl[CARET_DontChange]; + break; + } + default: { + return caretDirTbl[CARET_UnknownDirection]; + break; + } + } + return caretDirTbl[CARET_UnknownDirection]; + } + + + static char * + IsValidWindow(winPtr) + TkWindow *winPtr; + { + char *ret = NULL; + TkWindow *checkWinPtr = NULL; + if (winPtr == NULL) { + return NULL; + } + if (IsSetICState(winPtr->icAttr, IC_DESTROYED) || + IsSetICState(winPtr->icAttr, IC_ASSOC_WIN_DELETED)) { + return NULL; + } + ret = winPtr->pathName; + if (ret == NULL) { + return NULL; + } + /* + * Double check! + */ + checkWinPtr = (TkWindow *)Tk_NameToWindow(winPtr->mainPtr->interp, ret, (Tk_Window)winPtr); + if (checkWinPtr != winPtr) { + return NULL; + } + return ret; + } + + + static void + GenCallbackScriptGenericArgs(interp, cmd, path, class, objPtr) + Tcl_Interp *interp; + char *cmd; + char *path; + char *class; + Tcl_Obj *objPtr; + { + int lc; + char **lv; + int i; + if (Tcl_SplitList(interp, cmd, &lc, &lv) != TCL_OK) { + panic("illegal command string for IM callback."); + } + for (i = 0; i < lc; i++) { + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(lv[i], -1)); + } + ckfree((char *)lv); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(path, -1)); + Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(class, -1)); + } + + + static int + EvalIt(interp, objPtr) + Tcl_Interp *interp; + Tcl_Obj *objPtr; + { + int ret = TCL_ERROR; + Tcl_IncrRefCount(objPtr); + Tcl_ResetResult(interp); + #ifdef XIM_DEBUG + fprintf(stderr, "debug: call '%s'\n", Tcl_GetStringFromObj(objPtr, NULL)); + #endif /* XIM_DEBUG */ + ret = Tcl_EvalObj(interp, objPtr); + Tcl_DecrRefCount(objPtr); + return ret; + } + + + static int + IMPreeditStartCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XPointer callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + int ret = -1; + SetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return -1; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return -1; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("PreeditStart", -1)); + if (EvalIt(interp, cmdObj) == TCL_OK) { + int retVal = -1; + if (Tcl_GetIntFromObj(interp, Tcl_GetObjResult(interp), &retVal) == TCL_OK) { + ret = retVal; + } + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + #ifdef XIM_DEBUG + fprintf(stderr, "debug: PreeditStart ret %d\n", ret); + #endif /* XIM_DEBUG */ + TkpIMUnsetBarrier(winPtr->display); + return ret; + } + + + static void + IMPreeditDoneCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XPointer callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + ResetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("PreeditDone", -1)); + if (EvalIt(interp, cmdObj) == TCL_OK) { + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + TkpIMUnsetBarrier(winPtr->display); + return; + } + + + static void + IMPreeditDrawCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XIMPreeditDrawCallbackStruct *callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + SetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("PreeditDraw", -1)); + if (callData != NULL) { + Tcl_Obj *argObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + char numBuf[64]; + sprintf(numBuf, "%d", callData->caret); + Tcl_ListObjAppendElement(interp, argObj, Tcl_NewStringObj(numBuf, -1)); + sprintf(numBuf, "%d", callData->chg_first); + Tcl_ListObjAppendElement(interp, argObj, Tcl_NewStringObj(numBuf, -1)); + sprintf(numBuf, "%d", callData->chg_length); + Tcl_ListObjAppendElement(interp, argObj, Tcl_NewStringObj(numBuf, -1)); + AppendXIMTextToObj(interp, callData->text, argObj); + Tcl_IncrRefCount(argObj); + Tcl_AppendStringsToObj(cmdObj, " ", Tcl_GetStringFromObj(argObj, NULL), NULL); + Tcl_DecrRefCount(argObj); + } else { + Tcl_ListObjAppendElement(interp, cmdObj, Tcl_NewStringObj("", -1)); + } + if (EvalIt(interp, cmdObj) == TCL_OK) { + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + TkpIMUnsetBarrier(winPtr->display); + return; + } + + + static void + IMPreeditCaretCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XIMPreeditCaretCallbackStruct *callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + SetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("PreeditCaret", -1)); + if (callData != NULL) { + Tcl_Obj *argObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + char numBuf[64]; + sprintf(numBuf, "%d", callData->position); + Tcl_ListObjAppendElement(interp, argObj, + Tcl_NewStringObj(numBuf, -1)); + Tcl_ListObjAppendElement(interp, argObj, + Tcl_NewStringObj(IMCaretDirection2Str(callData->direction), -1)); + Tcl_ListObjAppendElement(interp, argObj, + Tcl_NewStringObj(IMCaretStyle2Str(callData->style), -1)); + Tcl_IncrRefCount(argObj); + Tcl_AppendStringsToObj(cmdObj, " ", Tcl_GetStringFromObj(argObj, NULL), NULL); + Tcl_DecrRefCount(argObj); + } else { + Tcl_ListObjAppendElement(interp, cmdObj, Tcl_NewStringObj("", -1)); + } + if (EvalIt(interp, cmdObj) == TCL_OK) { + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + TkpIMUnsetBarrier(winPtr->display); + return; + } + + + static void + IMStatusStartCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XPointer callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + SetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("StatusStart", -1)); + if (EvalIt(interp, cmdObj) == TCL_OK) { + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + TkpIMUnsetBarrier(winPtr->display); + return; + } + + + static void + IMStatusDoneCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XPointer callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + ResetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("StatusDone", -1)); + if (EvalIt(interp, cmdObj) == TCL_OK) { + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + TkpIMUnsetBarrier(winPtr->display); + return; + } + + + static void + IMStatusDrawCallback(ic, clientData, callData) + XIC ic; + XPointer clientData; + XIMStatusDrawCallbackStruct *callData; + { + TkWindow *winPtr = (TkWindow *)clientData; + char *pathName = IsValidWindow(winPtr); + SetICState(winPtr->icAttr, IC_IN_USE_RITE_NOW); + + if (pathName == NULL) { + return; + } + if (TkpIMIsDisplayInBarrier(winPtr->display)) { + return; + } else { + TkpIMSetBarrier(winPtr->display); + } + if (winPtr->icAttr->callbackCmd != NULL) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + Tcl_Obj *cmdObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + Tcl_Obj *result = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); + + Tcl_IncrRefCount(result); + + GenCallbackScriptGenericArgs(interp, + winPtr->icAttr->callbackCmd, + pathName, + winPtr->classUid, + cmdObj); + Tcl_ListObjAppendElement(interp, cmdObj, + Tcl_NewStringObj("StatusDraw", -1)); + if (callData != NULL) { + Tcl_Obj *argObj = Tcl_NewListObj(0, (Tcl_Obj **)NULL); + + switch ((XIMStatusDataType)(callData->type)) { + case XIMTextType: { + Tcl_ListObjAppendElement(interp, argObj, + Tcl_NewStringObj("text", -1)); + AppendXIMTextToObj(interp, callData->data.text, argObj); + break; + } + case XIMBitmapType: { + char numBuf[64]; + Tcl_ListObjAppendElement(interp, argObj, + Tcl_NewStringObj("bitmap", -1)); + sprintf(numBuf, "0x%08lx", callData->data.bitmap); + Tcl_ListObjAppendElement(interp, argObj, + Tcl_NewStringObj(numBuf, -1)); + break; + } + } + Tcl_IncrRefCount(argObj); + Tcl_AppendStringsToObj(cmdObj, " ", Tcl_GetStringFromObj(argObj, NULL), NULL); + Tcl_DecrRefCount(argObj); + } else { + Tcl_ListObjAppendElement(interp, cmdObj, Tcl_NewStringObj("", -1)); + } + if (EvalIt(interp, cmdObj) == TCL_OK) { + Tcl_SetObjResult(interp, result); + } else { + Tcl_BackgroundError(interp); + } + Tcl_DecrRefCount(result); + } + TkpIMUnsetBarrier(winPtr->display); + return; + } + + + static XVaNestedList + GenPreeditCallbackVaList(winPtr) + TkWindow *winPtr; + { + #define peCB(X) (winPtr->icAttr->peCB[X]) + #define peCBFunc(X) winPtr->icAttr->peCB[X].callback + #define peCBArg(X) winPtr->icAttr->peCB[X].client_data + + peCBArg(IM_PEStartCB) = + peCBArg(IM_PEDoneCB) = + peCBArg(IM_PEDrawCB) = + peCBArg(IM_PECaretCB) = (XPointer)winPtr; + + peCBFunc(IM_PEStartCB) = (XIMProc)IMPreeditStartCallback; + peCBFunc(IM_PEDoneCB) = (XIMProc)IMPreeditDoneCallback; + peCBFunc(IM_PEDrawCB) = (XIMProc)IMPreeditDrawCallback; + peCBFunc(IM_PECaretCB) = (XIMProc)IMPreeditCaretCallback; + + return XVaCreateNestedList(0, + XNPreeditStartCallback, &peCB(IM_PEStartCB), + XNPreeditDoneCallback, &peCB(IM_PEDoneCB), + XNPreeditDrawCallback, &peCB(IM_PEDrawCB), + XNPreeditCaretCallback, &peCB(IM_PECaretCB), + NULL); + } + + + static XVaNestedList + GenStatusCallbackVaList(winPtr) + TkWindow *winPtr; + { + #define stCB(X) (winPtr->icAttr->stCB[X]) + #define stCBFunc(X) winPtr->icAttr->stCB[X].callback + #define stCBArg(X) winPtr->icAttr->stCB[X].client_data + + stCBArg(IM_STStartCB) = + stCBArg(IM_STDoneCB) = + stCBArg(IM_STDrawCB) = (XPointer)winPtr; + + stCBFunc(IM_STStartCB) = (XIMProc)IMStatusStartCallback; + stCBFunc(IM_STDoneCB) = (XIMProc)IMStatusDoneCallback; + stCBFunc(IM_STDrawCB) = (XIMProc)IMStatusDrawCallback; + + return XVaCreateNestedList(0, + XNStatusStartCallback, &stCB(IM_STStartCB), + XNStatusDoneCallback, &stCB(IM_STDoneCB), + XNStatusDrawCallback, &stCB(IM_STDrawCB), + NULL); + } + + + + #ifdef XIM_DEBUG + Display *dpy = NULL; + char *Yes = "YES"; + char *No = "NO"; + char *Unknown = "unknown"; + + prologue (eventp, event_name) + XEvent *eventp; + char *event_name; + { + XAnyEvent *e = (XAnyEvent *) eventp; + + printf ("\n%s event, serial %ld, synthetic %s, window 0x%lx,\n", + event_name, e->serial, e->send_event ? Yes : No, e->window); + return; + } + + + do_KeyPress (eventp) + XEvent *eventp; + { + XKeyEvent *e = (XKeyEvent *) eventp; + KeySym ks; + char *ksname; + int nbytes; + char str[256+1]; + + nbytes = XLookupString (e, str, 256, &ks, NULL); + if (ks == NoSymbol) + ksname = "NoSymbol"; + else if (!(ksname = XKeysymToString (ks))) + ksname = "(no name)"; + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" state 0x%x, keycode %u (keysym 0x%x, %s), same_screen %s,\n", + e->state, e->keycode, ks, ksname, e->same_screen ? Yes : No); + if (nbytes < 0) nbytes = 0; + if (nbytes > 256) nbytes = 256; + str[nbytes] = '\0'; + printf (" XLookupString gives %d characters: \"%s\"\n", nbytes, str); + + return; + } + + do_KeyRelease (eventp) + XEvent *eventp; + { + do_KeyPress (eventp); /* since it has the same info */ + return; + } + + do_ButtonPress (eventp) + XEvent *eventp; + { + XButtonEvent *e = (XButtonEvent *) eventp; + + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" state 0x%x, button %u, same_screen %s\n", + e->state, e->button, e->same_screen ? Yes : No); + + return; + } + + do_ButtonRelease (eventp) + XEvent *eventp; + { + do_ButtonPress (eventp); /* since it has the same info */ + return; + } + + do_MotionNotify (eventp) + XEvent *eventp; + { + XMotionEvent *e = (XMotionEvent *) eventp; + + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" state 0x%x, is_hint %u, same_screen %s\n", + e->state, e->is_hint, e->same_screen ? Yes : No); + + return; + } + + do_EnterNotify (eventp) + XEvent *eventp; + { + XCrossingEvent *e = (XCrossingEvent *) eventp; + char *mode, *detail; + char dmode[10], ddetail[10]; + + switch (e->mode) { + case NotifyNormal: mode = "NotifyNormal"; break; + case NotifyGrab: mode = "NotifyGrab"; break; + case NotifyUngrab: mode = "NotifyUngrab"; break; + case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; + default: mode = dmode, sprintf (dmode, "%u", e->mode); break; + } + + switch (e->detail) { + case NotifyAncestor: detail = "NotifyAncestor"; break; + case NotifyVirtual: detail = "NotifyVirtual"; break; + case NotifyInferior: detail = "NotifyInferior"; break; + case NotifyNonlinear: detail = "NotifyNonlinear"; break; + case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; + case NotifyPointer: detail = "NotifyPointer"; break; + case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; + case NotifyDetailNone: detail = "NotifyDetailNone"; break; + default: detail = ddetail; sprintf (ddetail, "%u", e->detail); break; + } + + printf (" root 0x%lx, subw 0x%lx, time %lu, (%d,%d), root:(%d,%d),\n", + e->root, e->subwindow, e->time, e->x, e->y, e->x_root, e->y_root); + printf (" mode %s, detail %s, same_screen %s,\n", + mode, detail, e->same_screen ? Yes : No); + printf (" focus %s, state %u\n", e->focus ? Yes : No, e->state); + + return; + } + + do_LeaveNotify (eventp) + XEvent *eventp; + { + do_EnterNotify (eventp); /* since it has same information */ + return; + } + + do_FocusIn (eventp) + XEvent *eventp; + { + XFocusChangeEvent *e = (XFocusChangeEvent *) eventp; + char *mode, *detail; + char dmode[10], ddetail[10]; + + switch (e->mode) { + case NotifyNormal: mode = "NotifyNormal"; break; + case NotifyGrab: mode = "NotifyGrab"; break; + case NotifyUngrab: mode = "NotifyUngrab"; break; + case NotifyWhileGrabbed: mode = "NotifyWhileGrabbed"; break; + default: mode = dmode, sprintf (dmode, "%u", e->mode); break; + } + + switch (e->detail) { + case NotifyAncestor: detail = "NotifyAncestor"; break; + case NotifyVirtual: detail = "NotifyVirtual"; break; + case NotifyInferior: detail = "NotifyInferior"; break; + case NotifyNonlinear: detail = "NotifyNonlinear"; break; + case NotifyNonlinearVirtual: detail = "NotifyNonlinearVirtual"; break; + case NotifyPointer: detail = "NotifyPointer"; break; + case NotifyPointerRoot: detail = "NotifyPointerRoot"; break; + case NotifyDetailNone: detail = "NotifyDetailNone"; break; + default: detail = ddetail; sprintf (ddetail, "%u", e->detail); break; + } + + printf (" mode %s, detail %s\n", mode, detail); + return; + } + + do_FocusOut (eventp) + XEvent *eventp; + { + do_FocusIn (eventp); /* since it has same information */ + return; + } + + do_KeymapNotify (eventp) + XEvent *eventp; + { + XKeymapEvent *e = (XKeymapEvent *) eventp; + int i; + + printf (" keys: "); + for (i = 0; i < 32; i++) { + if (i == 16) printf ("\n "); + printf ("%-3u ", (unsigned int) e->key_vector[i]); + } + printf ("\n"); + return; + } + + do_Expose (eventp) + XEvent *eventp; + { + XExposeEvent *e = (XExposeEvent *) eventp; + + printf (" (%d,%d), width %d, height %d, count %d\n", + e->x, e->y, e->width, e->height, e->count); + return; + } + + do_GraphicsExpose (eventp) + XEvent *eventp; + { + XGraphicsExposeEvent *e = (XGraphicsExposeEvent *) eventp; + char *m; + char mdummy[10]; + + switch (e->major_code) { + case X_CopyArea: m = "CopyArea"; break; + case X_CopyPlane: m = "CopyPlane"; break; + default: m = mdummy; sprintf (mdummy, "%d", e->major_code); break; + } + + printf (" (%d,%d), width %d, height %d, count %d,\n", + e->x, e->y, e->width, e->height, e->count); + printf (" major %s, minor %d\n", m, e->minor_code); + return; + } + + do_NoExpose (eventp) + XEvent *eventp; + { + XNoExposeEvent *e = (XNoExposeEvent *) eventp; + char *m; + char mdummy[10]; + + switch (e->major_code) { + case X_CopyArea: m = "CopyArea"; break; + case X_CopyPlane: m = "CopyPlane"; break; + default: m = mdummy; sprintf (mdummy, "%d", e->major_code); break; + } + + printf (" major %s, minor %d\n", m, e->minor_code); + return; + } + + do_VisibilityNotify (eventp) + XEvent *eventp; + { + XVisibilityEvent *e = (XVisibilityEvent *) eventp; + char *v; + char vdummy[10]; + + switch (e->state) { + case VisibilityUnobscured: v = "VisibilityUnobscured"; break; + case VisibilityPartiallyObscured: v = "VisibilityPartiallyObscured"; break; + case VisibilityFullyObscured: v = "VisibilityFullyObscured"; break; + default: v = vdummy; sprintf (vdummy, "%d", e->state); break; + } + + printf (" state %s\n", v); + return; + } + + do_CreateNotify (eventp) + XEvent *eventp; + { + XCreateWindowEvent *e = (XCreateWindowEvent *) eventp; + + printf (" parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d\n", + e->parent, e->window, e->x, e->y, e->width, e->height); + printf ("border_width %d, override %s\n", + e->border_width, e->override_redirect ? Yes : No); + return; + } + + do_DestroyNotify (eventp) + XEvent *eventp; + { + XDestroyWindowEvent *e = (XDestroyWindowEvent *) eventp; + + printf (" event 0x%lx, window 0x%lx\n", e->event, e->window); + return; + } + + do_UnmapNotify (eventp) + XEvent *eventp; + { + XUnmapEvent *e = (XUnmapEvent *) eventp; + + printf (" event 0x%lx, window 0x%lx, from_configure %s\n", + e->event, e->window, e->from_configure ? Yes : No); + return; + } + + do_MapNotify (eventp) + XEvent *eventp; + { + XMapEvent *e = (XMapEvent *) eventp; + + printf (" event 0x%lx, window 0x%lx, override %s\n", + e->event, e->window, e->override_redirect ? Yes : No); + return; + } + + do_MapRequest (eventp) + XEvent *eventp; + { + XMapRequestEvent *e = (XMapRequestEvent *) eventp; + + printf (" parent 0x%lx, window 0x%lx\n", e->parent, e->window); + return; + } + + do_ReparentNotify (eventp) + XEvent *eventp; + { + XReparentEvent *e = (XReparentEvent *) eventp; + + printf (" event 0x%lx, window 0x%lx, parent 0x%lx,\n", + e->event, e->window, e->parent); + printf (" (%d,%d), override %s\n", e->x, e->y, + e->override_redirect ? Yes : No); + return; + } + + do_ConfigureNotify (eventp) + XEvent *eventp; + { + XConfigureEvent *e = (XConfigureEvent *) eventp; + + printf (" event 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n", + e->event, e->window, e->x, e->y, e->width, e->height); + printf (" border_width %d, above 0x%lx, override %s\n", + e->border_width, e->above, e->override_redirect ? Yes : No); + return; + } + + do_ConfigureRequest (eventp) + XEvent *eventp; + { + XConfigureRequestEvent *e = (XConfigureRequestEvent *) eventp; + char *detail; + char ddummy[10]; + + switch (e->detail) { + case Above: detail = "Above"; break; + case Below: detail = "Below"; break; + case TopIf: detail = "TopIf"; break; + case BottomIf: detail = "BottomIf"; break; + case Opposite: detail = "Opposite"; break; + default: detail = ddummy; sprintf (ddummy, "%d", e->detail); break; + } + + printf (" parent 0x%lx, window 0x%lx, (%d,%d), width %d, height %d,\n", + e->parent, e->window, e->x, e->y, e->width, e->height); + printf (" border_width %d, above 0x%lx, detail %s, value 0x%lx\n", + e->border_width, e->above, detail, e->value_mask); + return; + } + + do_GravityNotify (eventp) + XEvent *eventp; + { + XGravityEvent *e = (XGravityEvent *) eventp; + + printf (" event 0x%lx, window 0x%lx, (%d,%d)\n", + e->event, e->window, e->x, e->y); + return; + } + + do_ResizeRequest (eventp) + XEvent *eventp; + { + XResizeRequestEvent *e = (XResizeRequestEvent *) eventp; + + printf (" width %d, height %d\n", e->width, e->height); + return; + } + + do_CirculateNotify (eventp) + XEvent *eventp; + { + XCirculateEvent *e = (XCirculateEvent *) eventp; + char *p; + char pdummy[10]; + + switch (e->place) { + case PlaceOnTop: p = "PlaceOnTop"; break; + case PlaceOnBottom: p = "PlaceOnBottom"; break; + default: p = pdummy; sprintf (pdummy, "%d", e->place); break; + } + + printf (" event 0x%lx, window 0x%lx, place %s\n", + e->event, e->window, p); + return; + } + + do_CirculateRequest (eventp) + XEvent *eventp; + { + XCirculateRequestEvent *e = (XCirculateRequestEvent *) eventp; + char *p; + char pdummy[10]; + + switch (e->place) { + case PlaceOnTop: p = "PlaceOnTop"; break; + case PlaceOnBottom: p = "PlaceOnBottom"; break; + default: p = pdummy; sprintf (pdummy, "%d", e->place); break; + } + + printf (" parent 0x%lx, window 0x%lx, place %s\n", + e->parent, e->window, p); + return; + } + + do_PropertyNotify (eventp) + XEvent *eventp; + { + XPropertyEvent *e = (XPropertyEvent *) eventp; + char *aname = XGetAtomName (dpy, e->atom); + char *s; + char sdummy[10]; + + switch (e->state) { + case PropertyNewValue: s = "PropertyNewValue"; break; + case PropertyDelete: s = "PropertyDelete"; break; + default: s = sdummy; sprintf (sdummy, "%d", e->state); break; + } + + printf (" atom 0x%lx (%s), time %lu, state %s\n", + e->atom, aname ? aname : Unknown, e->time, s); + + if (aname) XFree (aname); + return; + } + + do_SelectionClear (eventp) + XEvent *eventp; + { + XSelectionClearEvent *e = (XSelectionClearEvent *) eventp; + char *sname = XGetAtomName (dpy, e->selection); + + printf (" selection 0x%lx (%s), time %lu\n", + e->selection, sname ? sname : Unknown, e->time); + + if (sname) XFree (sname); + return; + } + + do_SelectionRequest (eventp) + XEvent *eventp; + { + XSelectionRequestEvent *e = (XSelectionRequestEvent *) eventp; + char *sname = XGetAtomName (dpy, e->selection); + char *tname = XGetAtomName (dpy, e->target); + char *pname = XGetAtomName (dpy, e->property); + + printf (" owner 0x%lx, requestor 0x%lx, selection 0x%lx (%s),\n", + e->owner, e->requestor, e->selection, sname ? sname : Unknown); + printf (" target 0x%lx (%s), property 0x%lx (%s), time %lu\n", + e->target, tname ? tname : Unknown, e->property, + pname ? pname : Unknown, e->time); + + if (sname) XFree (sname); + if (tname) XFree (tname); + if (pname) XFree (pname); + + return; + } + + do_SelectionNotify (eventp) + XEvent *eventp; + { + XSelectionEvent *e = (XSelectionEvent *) eventp; + char *sname = XGetAtomName (dpy, e->selection); + char *tname = XGetAtomName (dpy, e->target); + char *pname = XGetAtomName (dpy, e->property); + + printf (" selection 0x%lx (%s), target 0x%lx (%s),\n", + e->selection, sname ? sname : Unknown, e->target, + tname ? tname : Unknown); + printf (" property 0x%lx (%s), time %lu\n", + e->property, pname ? pname : Unknown, e->time); + + if (sname) XFree (sname); + if (tname) XFree (tname); + if (pname) XFree (pname); + + return; + } + + do_ColormapNotify (eventp) + XEvent *eventp; + { + XColormapEvent *e = (XColormapEvent *) eventp; + char *s; + char sdummy[10]; + + switch (e->state) { + case ColormapInstalled: s = "ColormapInstalled"; break; + case ColormapUninstalled: s = "ColormapUninstalled"; break; + default: s = sdummy; sprintf (sdummy, "%d", e->state); break; + } + + printf (" colormap 0x%lx, new %s, state %s\n", + e->colormap, e->new ? Yes : No, s); + return; + } + + do_ClientMessage (eventp) + XEvent *eventp; + { + XClientMessageEvent *e = (XClientMessageEvent *) eventp; + char *mname = XGetAtomName (dpy, e->message_type); + + printf (" message_type 0x%lx (%s), format %d\n", + e->message_type, mname ? mname : Unknown, e->format); + + if (mname) XFree (mname); + return; + } + + do_MappingNotify (eventp) + XEvent *eventp; + { + XMappingEvent *e = (XMappingEvent *) eventp; + char *r; + char rdummy[10]; + + switch (e->request) { + case MappingModifier: r = "MappingModifier"; break; + case MappingKeyboard: r = "MappingKeyboard"; break; + case MappingPointer: r = "MappingPointer"; break; + default: r = rdummy; sprintf (rdummy, "%d", e->request); break; + } + + printf (" request %s, first_keycode %d, count %d\n", + r, e->first_keycode, e->count); + return; + } + + + void + DumpXEvent(display, event) + Display *display; + XEvent *event; + { + dpy = display; + switch (event->type) { + case KeyPress: { + prologue (event, "KeyPress"); + do_KeyPress (event); + break; + } + case KeyRelease: { + prologue (event, "KeyRelease"); + do_KeyRelease (event); + break; + } + case ButtonPress: { + prologue (event, "ButtonPress"); + do_ButtonPress (event); + break; + } + case ButtonRelease: { + prologue (event, "ButtonRelease"); + do_ButtonRelease (event); + break; + } + case MotionNotify: { + prologue (event, "MotionNotify"); + do_MotionNotify (event); + break; + } + case EnterNotify: { + prologue (event, "EnterNotify"); + do_EnterNotify (event); + break; + } + case LeaveNotify: { + prologue (event, "LeaveNotify"); + do_LeaveNotify (event); + break; + } + case FocusIn: { + prologue (event, "FocusIn"); + do_FocusIn (event); + break; + } + case FocusOut: { + prologue (event, "FocusOut"); + do_FocusOut (event); + break; + } + case KeymapNotify: { + prologue (event, "KeymapNotify"); + do_KeymapNotify (event); + break; + } + case Expose: { + prologue (event, "Expose"); + do_Expose (event); + break; + } + case GraphicsExpose: { + prologue (event, "GraphicsExpose"); + do_GraphicsExpose (event); + break; + } + case NoExpose: { + prologue (event, "NoExpose"); + do_NoExpose (event); + break; + } + case VisibilityNotify: { + prologue (event, "VisibilityNotify"); + do_VisibilityNotify (event); + break; + } + case CreateNotify: { + prologue (event, "CreateNotify"); + do_CreateNotify (event); + break; + } + case DestroyNotify: { + prologue (event, "DestroyNotify"); + do_DestroyNotify (event); + break; + } + case UnmapNotify: { + prologue (event, "UnmapNotify"); + do_UnmapNotify (event); + break; + } + case MapNotify: { + prologue (event, "MapNotify"); + do_MapNotify (event); + break; + } + case MapRequest: { + prologue (event, "MapRequest"); + do_MapRequest (event); + break; + } + case ReparentNotify: { + prologue (event, "ReparentNotify"); + do_ReparentNotify (event); + break; + } + case ConfigureNotify: { + prologue (event, "ConfigureNotify"); + do_ConfigureNotify (event); + break; + } + case ConfigureRequest: { + prologue (event, "ConfigureRequest"); + do_ConfigureRequest (event); + break; + } + case GravityNotify: { + prologue (event, "GravityNotify"); + do_GravityNotify (event); + break; + } + case ResizeRequest: { + prologue (event, "ResizeRequest"); + do_ResizeRequest (event); + break; + } + case CirculateNotify: { + prologue (event, "CirculateNotify"); + do_CirculateNotify (event); + break; + } + case CirculateRequest: { + prologue (event, "CirculateRequest"); + do_CirculateRequest (event); + break; + } + case PropertyNotify: { + prologue (event, "PropertyNotify"); + do_PropertyNotify (event); + break; + } + case SelectionClear: { + prologue (event, "SelectionClear"); + do_SelectionClear (event); + break; + } + case SelectionRequest: { + prologue (event, "SelectionRequest"); + do_SelectionRequest (event); + break; + } + case SelectionNotify: { + prologue (event, "SelectionNotify"); + do_SelectionNotify (event); + break; + } + case ColormapNotify: { + prologue (event, "ColormapNotify"); + do_ColormapNotify (event); + break; + } + case ClientMessage: { + prologue (event, "ClientMessage"); + do_ClientMessage (event); + break; + } + case MappingNotify: { + prologue (event, "MappingNotify"); + do_MappingNotify (event); + break; + } + default: { + printf ("Unknown event type %d\n", event->type); + break; + } + } + } + #endif /* XIM_DEBUG */ + + #endif /* XIM_IMPROVE */ + #endif /* TK_USE_INPUT_METHODS */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/makefile.bc ./win/makefile.bc *** ../../tk8.0.5/win/makefile.bc Fri Feb 5 06:02:58 1999 --- ./win/makefile.bc Fri Mar 12 06:55:31 1999 *************** *** 19,25 **** ROOT = .. TMPDIR = . TOOLS = c:\bc45 ! TCLDIR = ..\..\tcl8.0.5 # uncomment the following line to compile with symbols #DEBUG=1 --- 19,25 ---- ROOT = .. TMPDIR = . TOOLS = c:\bc45 ! TCLDIR = ..\..\tcl8.0.5jp # uncomment the following line to compile with symbols #DEBUG=1 *************** *** 27,32 **** --- 27,34 ---- # uncomment the following line to compile with TCL_MEM_DEBUG #DEBUGDEFINES =TCL_MEM_DEBUG + KANJI_FLAGS = -DKANJI -DHANDLE_KANJI_PATHNAME -DBUGFIX -DIME_AWARE + # # Borland C++ tools # *************** *** 59,65 **** !endif DEFINES = MT;_RTLDLL;STRICT;$(DEBUGDEFINES) ! PROJECTCCFLAGS= $(DEBUGCCFLAGS) -w-par -w-stu LNFLAGS_exe = -Tpe -aa -c $(DEBUGLDFLAGS) $(BORLAND)\lib\c0w32 LNFLAGS_dll = -Tpd -aa -c $(DEBUGLDFLAGS) $(BORLAND)\lib\c0d32 --- 61,67 ---- !endif DEFINES = MT;_RTLDLL;STRICT;$(DEBUGDEFINES) ! PROJECTCCFLAGS= $(DEBUGCCFLAGS) -w-par -w-stu $(KANJI_FLAGS) LNFLAGS_exe = -Tpe -aa -c $(DEBUGLDFLAGS) $(BORLAND)\lib\c0w32 LNFLAGS_dll = -Tpd -aa -c $(DEBUGLDFLAGS) $(BORLAND)\lib\c0d32 *************** *** 142,147 **** --- 144,150 ---- $(TMPDIR)\tkCmds.obj \ $(TMPDIR)\tkColor.obj \ $(TMPDIR)\tkConfig.obj \ + $(TMPDIR)\tkCtext.obj \ $(TMPDIR)\tkCursor.obj \ $(TMPDIR)\tkEntry.obj \ $(TMPDIR)\tkError.obj \ *************** *** 161,166 **** --- 164,170 ---- $(TMPDIR)\tkImgPPM.obj \ $(TMPDIR)\tkImgPhoto.obj \ $(TMPDIR)\tkImgUtil.obj \ + $(TMPDIR)\tkKinsoku.obj \ $(TMPDIR)\tkListbox.obj \ $(TMPDIR)\tkMacWinMenu.obj \ $(TMPDIR)\tkMain.obj \ *************** *** 187,199 **** $(TMPDIR)\tkTrig.obj \ $(TMPDIR)\tkUtil.obj \ $(TMPDIR)\tkVisual.obj \ $(TMPDIR)\tkWindow.obj ! TCLDLL = tcl80.dll ! TCLLIB = tcl80.lib ! TKDLL = tk80.dll ! TKLIB = tk80.lib ! WISH = wish80.exe TKTEST = tktest.exe # --- 191,204 ---- $(TMPDIR)\tkTrig.obj \ $(TMPDIR)\tkUtil.obj \ $(TMPDIR)\tkVisual.obj \ + $(TMPDIR)\tkWFont.obj \ $(TMPDIR)\tkWindow.obj ! TCLDLL = tcl80jp.dll ! TCLLIB = tcl80jp.lib ! TKDLL = tk80jp.dll ! TKLIB = tk80jp.lib ! WISH = wish80jp.exe TKTEST = tktest.exe # diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/makefile.vc ./win/makefile.vc *** ../../tk8.0.5/win/makefile.vc Fri Feb 12 09:50:21 1999 --- ./win/makefile.vc Tue Apr 6 20:04:18 1999 *************** *** 28,34 **** ROOT = .. TOOLS32 = c:\program files\devstudio\vc TOOLS32_rc = c:\program files\devstudio\sharedide ! TCLDIR = ..\..\tcl8.0.5 INSTALLDIR = c:\program files\tcl # Set this to the appropriate value of /MACHINE: for your platform --- 28,34 ---- ROOT = .. TOOLS32 = c:\program files\devstudio\vc TOOLS32_rc = c:\program files\devstudio\sharedide ! TCLDIR = ..\..\tcl8.0.5jp INSTALLDIR = c:\program files\tcl # Set this to the appropriate value of /MACHINE: for your platform *************** *** 40,45 **** --- 40,47 ---- # uncomment the following two lines to compile with TCL_MEM_DEBUG #DEBUGDEFINES =-DTCL_MEM_DEBUG + KANJI_FLAGS = -DKANJI -DHANDLE_KANJI_PATHNAME -DBUGFIX -DIME_AWARE + ###################################################################### # Do not modify below this line ###################################################################### *************** *** 47,54 **** TCLNAMEPREFIX = tcl TKNAMEPREFIX = tk WISHNAMEPREFIX = wish ! VERSION = 80 ! DOTVERSION = 8.0 BINROOT = . !IF "$(NODEBUG)" == "1" --- 49,56 ---- TCLNAMEPREFIX = tcl TKNAMEPREFIX = tk WISHNAMEPREFIX = wish ! VERSION = 80jp ! DOTVERSION = 8.0jp BINROOT = . !IF "$(NODEBUG)" == "1" *************** *** 144,149 **** --- 146,152 ---- $(TMPDIR)\tkCmds.obj \ $(TMPDIR)\tkColor.obj \ $(TMPDIR)\tkConfig.obj \ + $(TMPDIR)\tkCtext.obj \ $(TMPDIR)\tkCursor.obj \ $(TMPDIR)\tkEntry.obj \ $(TMPDIR)\tkError.obj \ *************** *** 163,168 **** --- 166,172 ---- $(TMPDIR)\tkImgPPM.obj \ $(TMPDIR)\tkImgPhoto.obj \ $(TMPDIR)\tkImgUtil.obj \ + $(TMPDIR)\tkKinsoku.obj \ $(TMPDIR)\tkListbox.obj \ $(TMPDIR)\tkMacWinMenu.obj \ $(TMPDIR)\tkMain.obj \ *************** *** 189,194 **** --- 193,199 ---- $(TMPDIR)\tkTrig.obj \ $(TMPDIR)\tkUtil.obj \ $(TMPDIR)\tkVisual.obj \ + $(TMPDIR)\tkWFont.obj \ $(TMPDIR)\tkWindow.obj cc32 = "$(TOOLS32)\bin\cl.exe" *************** *** 244,250 **** !ENDIF baselibs = kernel32.lib $(optlibs) advapi32.lib ! winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib guilibs = $(libc) $(winlibs) guilibsdll = $(libcdll) $(winlibs) --- 249,255 ---- !ENDIF baselibs = kernel32.lib $(optlibs) advapi32.lib ! winlibs = $(baselibs) user32.lib gdi32.lib comdlg32.lib winspool.lib imm32.lib guilibs = $(libc) $(winlibs) guilibsdll = $(libcdll) $(winlibs) *************** *** 266,272 **** !ENDIF # declarations common to all compiler options ! ccommon = -c -W3 -nologo -Fp$(TMPDIR)\ -YX !IF "$(MACHINE)" == "IX86" cflags = $(ccommon) -D_X86_=1 --- 271,277 ---- !ENDIF # declarations common to all compiler options ! ccommon = -c -W3 -nologo -Fp$(TMPDIR)\ -YX $(KANJI_FLAGS) !IF "$(MACHINE)" == "IX86" cflags = $(ccommon) -D_X86_=1 *************** *** 302,308 **** all: setup $(WISH) test: setup $(TKTEST) ! install: install-binaries install-libraries plugin: setup $(TKPLUGINDLL) $(WISHP) tktest: setup $(TKTEST) --- 307,313 ---- all: setup $(WISH) test: setup $(TKTEST) ! install: install-binaries install-libraries install-demosjp plugin: setup $(TKPLUGINDLL) $(WISHP) tktest: setup $(TKTEST) *************** *** 330,335 **** --- 335,351 ---- xcopy "$(ROOT)\library\images" "$(SCRIPT_INSTALL_DIR)\images" xcopy "$(ROOT)\library\demos" "$(SCRIPT_INSTALL_DIR)\demos" xcopy "$(ROOT)\library\demos\images" "$(SCRIPT_INSTALL_DIR)\demos\images" + @del "$(SCRIPT_INSTALL_DIR)\demos\widget.tcl" + move "$(SCRIPT_INSTALL_DIR)\demos\widget" "$(SCRIPT_INSTALL_DIR)\demos\widget.tcl" + + install-demosjp: + @mkd "$(SCRIPT_INSTALL_DIR)" + @mkd "$(SCRIPT_INSTALL_DIR)\demos.jp" + @mkd "$(SCRIPT_INSTALL_DIR)\demos.jp\images" + xcopy "$(ROOT)\library\demos.jp" "$(SCRIPT_INSTALL_DIR)\demos.jp" + xcopy "$(ROOT)\library\demos\images" "$(SCRIPT_INSTALL_DIR)\demos.jp\images" + @del "$(SCRIPT_INSTALL_DIR)\demos.jp\widget.tcl" + move "$(SCRIPT_INSTALL_DIR)\demos.jp\widget" "$(SCRIPT_INSTALL_DIR)\demos.jp\widget.tcl" $(TKLIB): $(TKDLL) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/mkd.bat ./win/mkd.bat *** ../../tk8.0.5/win/mkd.bat Thu Oct 1 05:19:00 1998 --- ./win/mkd.bat Fri Mar 12 00:39:38 1999 *************** *** 1,21 **** ! @echo off ! rem RCS: @(#) $Id: mkd.bat,v 1.3 1998/09/30 20:19:00 escoffon Exp $ ! ! if exist %1\tag.txt goto end ! ! if "%OS%" == "Windows_NT" goto winnt ! ! md %1 ! if errorlevel 1 goto end ! ! goto success ! ! :winnt ! md %1 ! if errorlevel 1 goto end ! ! :success ! echo TAG >%1\tag.txt ! echo created directory %1 ! ! :end --- 1,21 ---- ! @echo off ! rem RCS: @(#) $Id: mkd.bat,v 1.4 1999/03/11 15:39:38 m-hirano Exp $ ! ! if exist %1\tag.txt goto end ! ! if "%OS%" == "Windows_NT" goto winnt ! ! md %1 ! if errorlevel 1 goto end ! ! goto success ! ! :winnt ! md %1 ! if errorlevel 1 goto end ! ! :success ! echo TAG >%1\tag.txt ! echo created directory %1 ! ! :end diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/rmd.bat ./win/rmd.bat *** ../../tk8.0.5/win/rmd.bat Thu Oct 1 05:19:59 1998 --- ./win/rmd.bat Fri Mar 12 00:39:38 1999 *************** *** 1,25 **** ! @echo off ! rem RCS: @(#) $Id: rmd.bat,v 1.3 1998/09/30 20:19:59 escoffon Exp $ ! ! if not exist %1\tag.txt goto end ! ! echo Removing directory %1 ! ! if "%OS%" == "Windows_NT" goto winnt ! ! cd %1 ! if errorlevel 1 goto end ! del *.* ! cd .. ! rmdir %1 ! if errorlevel 1 goto end ! goto success ! ! :winnt ! rmdir %1 /s /q ! if errorlevel 1 goto end ! ! :success ! echo deleted directory %1 ! ! :end --- 1,25 ---- ! @echo off ! rem RCS: @(#) $Id: rmd.bat,v 1.4 1999/03/11 15:39:38 m-hirano Exp $ ! ! if not exist %1\tag.txt goto end ! ! echo Removing directory %1 ! ! if "%OS%" == "Windows_NT" goto winnt ! ! cd %1 ! if errorlevel 1 goto end ! del *.* ! cd .. ! rmdir %1 ! if errorlevel 1 goto end ! goto success ! ! :winnt ! rmdir %1 /s /q ! if errorlevel 1 goto end ! ! :success ! echo deleted directory %1 ! ! :end diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWin.h ./win/tkWin.h *** ../../tk8.0.5/win/tkWin.h Tue Sep 15 03:23:59 1998 --- ./win/tkWin.h Fri Mar 12 00:39:39 1999 *************** *** 57,62 **** --- 57,65 ---- EXTERN int Tk_TranslateWinEvent _ANSI_ARGS_((HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)); + #if defined(KANJI) && defined(IME_AWARE) + EXTERN HFONT Tk_GetHFONT _ANSI_ARGS_((Tk_Font tkfont)); + #endif /* KANJI && IME_AWARE */ # undef TCL_STORAGE_CLASS # define TCL_STORAGE_CLASS DLLIMPORT diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinButton.c ./win/tkWinButton.c *** ../../tk8.0.5/win/tkWinButton.c Tue Sep 15 03:23:59 1998 --- ./win/tkWinButton.c Fri Mar 12 00:39:39 1999 *************** *** 13,18 **** --- 13,21 ---- */ #define OEMRESOURCE + #ifdef KANJI + #define TK_KANJI_OK + #endif /* KANJI */ #include "tkWinInt.h" #include "tkButton.h" *************** *** 671,677 **** --- 674,687 ---- width = butPtr->textWidth; height = butPtr->textHeight; + #ifdef TK_KANJI_OK + { + wchar wTmp = '0'; + avgWidth = Tk_TextWidth(butPtr->tkfont, &wTmp, 1); + } + #else avgWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); + #endif /* TK_KANJI_OK */ Tk_GetFontMetrics(butPtr->tkfont, &fm); if (butPtr->width > 0) { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinClipboard.c ./win/tkWinClipboard.c *** ../../tk8.0.5/win/tkWinClipboard.c Tue Sep 15 03:23:59 1998 --- ./win/tkWinClipboard.c Fri Mar 19 00:21:25 1999 *************** *** 36,42 **** --- 36,46 ---- */ int + #ifdef KANJI + TkSelGetSelection(interp, tkwin, selection, target, proc, clientData, typeAtomPtr) + #else TkSelGetSelection(interp, tkwin, selection, target, proc, clientData) + #endif /* KANJI */ Tcl_Interp *interp; /* Interpreter to use for reporting * errors. */ Tk_Window tkwin; /* Window on whose behalf to retrieve *************** *** 48,60 **** --- 52,81 ---- Tk_GetSelProc *proc; /* Procedure to call to process the * selection, once it has been retrieved. */ ClientData clientData; /* Arbitrary value to pass to proc. */ + #ifdef KANJI + Atom *typeAtomPtr; + #endif /* KANJI */ { char *data, *buffer, *destPtr; HGLOBAL handle; int result, length; if ((selection == Tk_InternAtom(tkwin, "CLIPBOARD")) + #ifdef KANJI + && (target == XA_STRING || + target == Tk_UsefulAtom(((TkWindow *)tkwin), compoundTextAtom) || + target == Tk_UsefulAtom(((TkWindow *)tkwin), textAtom))) { + if (typeAtomPtr != NULL) { + if (target == Tk_UsefulAtom(((TkWindow *)tkwin), compoundTextAtom) || + target == Tk_UsefulAtom(((TkWindow *)tkwin), textAtom)) { + *typeAtomPtr = Tk_UsefulAtom(((TkWindow *)tkwin), compoundTextAtom); + } else { + *typeAtomPtr = None; + } + } + #else && (target == XA_STRING)) { + #endif if (OpenClipboard(NULL)) { handle = GetClipboardData(CF_TEXT); if (handle != NULL) { *************** *** 167,173 **** --- 188,200 ---- for (targetPtr = dispPtr->clipTargetPtr; targetPtr != NULL; targetPtr = targetPtr->nextPtr) { + #ifdef KANJI + if (targetPtr->type == XA_STRING || + targetPtr->type == dispPtr->compoundTextAtom || + targetPtr->type == dispPtr->textAtom) + #else if (targetPtr->type == XA_STRING) + #endif break; } length = 0; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinCursor.c ./win/tkWinCursor.c *** ../../tk8.0.5/win/tkWinCursor.c Tue Sep 15 03:23:59 1998 --- ./win/tkWinCursor.c Fri Mar 12 00:39:40 1999 *************** *** 106,112 **** --- 106,119 ---- cursorPtr->system = 1; } if (cursorPtr->winCursor == NULL) { + #ifdef KANJI + char *nstr = TkWinConvertToNativeString(string); + cursorPtr->winCursor = LoadCursor(Tk_GetHINSTANCE(), nstr); + if (nstr != string) + ckfree(nstr); + #else /* KANJI */ cursorPtr->winCursor = LoadCursor(Tk_GetHINSTANCE(), string); + #endif /* KANJI */ cursorPtr->system = 0; } if (cursorPtr->winCursor == NULL) { diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinDefault.h ./win/tkWinDefault.h *** ../../tk8.0.5/win/tkWinDefault.h Tue Sep 15 03:23:59 1998 --- ./win/tkWinDefault.h Fri Mar 12 00:39:41 1999 *************** *** 28,34 **** --- 28,38 ---- #define BLACK "Black" #define WHITE "White" + #ifdef KANJI + #define CTL_FONT "defaultgui" + #else #define CTL_FONT "{MS Sans Serif} 8" + #endif #define NORMAL_BG "SystemButtonFace" #define NORMAL_FG "SystemButtonText" #define ACTIVE_BG NORMAL_BG diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinDialog.c ./win/tkWinDialog.c *** ../../tk8.0.5/win/tkWinDialog.c Tue Sep 15 03:23:59 1998 --- ./win/tkWinDialog.c Fri Mar 12 00:39:41 1999 *************** *** 348,354 **** --- 348,361 ---- ccPtr = (CHOOSECOLOR*)lParam; pCustData = (ChooseColorData*)(ccPtr->lCustData); if (pCustData->title && *(pCustData->title)) { + #ifdef KANJI + char *nstr = TkWinConvertToNativeString(pCustData->title); + SetWindowText(hDlg, (LPCSTR)nstr); + if (nstr != pCustData->title) + ckfree(nstr); + #else /* KANJI */ SetWindowText(hDlg, (LPCSTR)pCustData->title); + #endif /* KANJI */ } return TRUE; *************** *** 491,500 **** --- 498,520 ---- * Change the pathname to the Tcl "normalized" pathname, where * back slashes are used instead of forward slashes */ + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + if (IS_KANJISTART(UCHAR(*p))) { + p += Tcl_KanjiSkip(p, NULL, NULL) - 1; + } else + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ if (*p == '\\') { *p = '/'; } } + #ifdef KANJI + if (Tcl_KanjiCode(interp) != TCL_SJIS) { + char *istr = Tcl_ConvertToInternal(interp, custData->szFile, NULL); + Tcl_AppendResult(interp, istr, NULL); + if (istr != custData->szFile) + ckfree(istr); + } else + #endif /* KANJI */ Tcl_AppendResult(interp, custData->szFile, NULL); tclCode = TCL_OK; } else { *************** *** 508,513 **** --- 528,541 ---- if (ofnPtr->lpstrFilter) { ckfree((char*)ofnPtr->lpstrFilter); } + #ifdef KANJI + if (ofnPtr->lpstrDefExt) { + ckfree((char*)ofnPtr->lpstrDefExt); + } + if (ofnPtr->lpstrTitle) { + ckfree((char*)ofnPtr->lpstrTitle); + } + #endif /* KANJI */ return tclCode; } *************** *** 544,549 **** --- 572,580 ---- int doneFilter = 0; int windowsMajorVersion; Tcl_DString buffer; + #ifdef KANJI + char *nstr; + #endif /* KANJI */ custData = (OpenFileData*)ckalloc(sizeof(OpenFileData)); custData->interp = interp; *************** *** 594,600 **** --- 625,639 ---- if (strncmp(argv[i], "-defaultextension", len)==0) { if (v==argc) {goto arg_missing;} + #ifdef KANJI + ofnPtr->lpstrDefExt = TkWinConvertToNativeString(argv[v]); + if (ofnPtr->lpstrDefExt == argv[v]) { + ofnPtr->lpstrDefExt = ckalloc(strlen(argv[v]) + 1); + strcpy((char *)ofnPtr->lpstrDefExt, argv[v]); + } + #else /* KANJI */ ofnPtr->lpstrDefExt = argv[v]; + #endif /* KANJI */ if (ofnPtr->lpstrDefExt[0] == '.') { /* Windows will insert the dot for us */ ofnPtr->lpstrDefExt ++; *************** *** 603,611 **** --- 642,662 ---- else if (strncmp(argv[i], "-filetypes", len)==0) { if (v==argc) {goto arg_missing;} + #ifdef KANJI + nstr = TkWinConvertToNativeString(argv[v]); + if (MakeFilter(interp, ofnPtr, nstr) != TCL_OK) { + if (nstr != argv[v]) + ckfree(nstr); + return TCL_ERROR; + } + if (nstr != argv[v]) { + ckfree(nstr); + } + #else /* KANJI */ if (MakeFilter(interp, ofnPtr, argv[v]) != TCL_OK) { return TCL_ERROR; } + #endif /* KANJI */ doneFilter = 1; } else if (strncmp(argv[i], "-initialdir", len)==0) { *************** *** 614,621 **** --- 665,680 ---- if (Tcl_TranslateFileName(interp, argv[v], &buffer) == NULL) { return TCL_ERROR; } + #ifdef KANJI + ofnPtr->lpstrInitialDir = TkWinConvertToNativeString(Tcl_DStringValue(&buffer)); + if (ofnPtr->lpstrInitialDir == Tcl_DStringValue(&buffer)) { + ofnPtr->lpstrInitialDir = ckalloc(Tcl_DStringLength(&buffer)+1); + strcpy((char*)ofnPtr->lpstrInitialDir, Tcl_DStringValue(&buffer)); + } + #else /* KANJI */ ofnPtr->lpstrInitialDir = ckalloc(Tcl_DStringLength(&buffer)+1); strcpy((char*)ofnPtr->lpstrInitialDir, Tcl_DStringValue(&buffer)); + #endif /* KANJI */ Tcl_DStringFree(&buffer); } else if (strncmp(argv[i], "-initialfile", len)==0) { *************** *** 624,630 **** --- 683,696 ---- if (Tcl_TranslateFileName(interp, argv[v], &buffer) == NULL) { return TCL_ERROR; } + #ifdef KANJI + nstr = TkWinConvertToNativeString(Tcl_DStringValue(&buffer)); + strcpy(ofnPtr->lpstrFile, nstr); + if (nstr != Tcl_DStringValue(&buffer)) + ckfree(nstr); + #else /* KANJI */ strcpy(ofnPtr->lpstrFile, Tcl_DStringValue(&buffer)); + #endif /* KANJI */ Tcl_DStringFree(&buffer); } else if (strncmp(argv[i], "-parent", len)==0) { *************** *** 638,644 **** --- 704,718 ---- else if (strncmp(argv[i], "-title", len)==0) { if (v==argc) {goto arg_missing;} + #ifdef KANJI + ofnPtr->lpstrTitle = TkWinConvertToNativeString(argv[v]); + if (ofnPtr->lpstrTitle == argv[v]) { + ofnPtr->lpstrTitle = ckalloc(strlen(argv[v]) + 1); + strcpy((char *)ofnPtr->lpstrTitle, argv[v]); + } + #else /* KANJI */ ofnPtr->lpstrTitle = argv[v]; + #endif /* KANJI */ } else { Tcl_AppendResult(interp, "unknown option \"", *************** *** 837,842 **** --- 911,919 ---- int code, oldMode; char *defaultBtn = NULL; int defaultBtnIdx = -1; + #ifdef KANJI + char *nstr[2]; + #endif for (i=1; i= 0x81 && (c) <= 0x9f) || ((c) >= 0xe0 && (c) <= 0xfc)) + + static int + EncodeSJISrange(ss, ws, sn) + unsigned char *ss; + wchar *ws; + int sn; + { + int c, c1; + int n = 0; + + while( sn-- > 0 && (c = *ss++) != 0 ) { + if( IS_SJIS(c) ) { + sn--; + c1 = *ss++; + c -= (c>=0xa0) ? 0xc1 : 0x81; + if( ws ) { + if( c1 >= 0x9f ) { + *ws++ = ((c<<9) + 0x2200 + c1 - 0x7e) | 0x8080; + } else { + *ws++ = ((c<<9) + 0x2100 + c1 + - ((c1<=0x7e) ? 0x1f : 0x20)) | 0x8080; + } + } + n++; + } else { + if( ws ) *ws++ = c; + n++; + } + } + if( sn >= 0 && ws ) *ws = 0; + + return n; + } + + static int + DecodeSJISrange(ws, ss, wn) + wchar *ws; + unsigned char *ss; + int wn; + { + int c1, c2; + int n = 0; + + while( wn-- > 0 && (c1 = *ws++) != 0 ) { + switch( c1 & 0x8080 ) { + case 0: + case 0x80: + if( ss ) *ss++ = c1 & 0xff; + n++; + break; + case 0x8080: + c2 = c1 & 0x7f; + c1 = (c1 >> 8) & 0x7f; + if( ss ) { + *ss++ = (c1 - 0x21) / 2 + ((c1 <= 0x5e) ? 0x81 : 0xc1); + if( c1 & 1 ) { /* odd */ + *ss++ = c2 + ((c2 <= 0x5f) ? 0x1f : 0x20); + } else { + *ss++ = c2 + 0x7e; + } + } + n += 2; + break; + } + } + if( wn >= 0 && ss ) *ss = '\0'; + + return n; + } + + int + TkpConvertPointToPixel(tkwin, pointsize) + Tk_Window tkwin; + int pointsize; + { + double rDPI = ((double)(WidthOfScreen(Tk_Screen(tkwin))) / + (double)(WidthMMOfScreen(Tk_Screen(tkwin))) * 25.4); + double ret = (double)(pointsize) * rDPI / 72.0 + 0.5; + return (int)ret; + } + + + int + TkpConvertPixelToPoint(tkwin, pixelsize) + Tk_Window tkwin; + int pixelsize; + { + /* 72.0 : pointsize = rDPI : pixelsize */ + double rDPI = ((double)(WidthOfScreen(Tk_Screen(tkwin))) / + (double)(WidthMMOfScreen(Tk_Screen(tkwin))) * 25.4); + double ret = (double)(pixelsize) * 72.0 / rDPI + 0.5; + return (int)ret; + } + #endif /* KANJI */ /* *--------------------------------------------------------------------------- *************** *** 148,153 **** --- 252,280 ---- window = Tk_WindowId(((TkWindow *) tkwin)->mainPtr->winPtr); hwnd = (window == None) ? NULL : TkWinGetHWND(window); + #ifdef KANJI + if (faPtr->fontType == TK_FONT_COMPOUND) { + WinFont *fontPtr = (WinFont *)tkFontPtr; + if (fontPtr == (WinFont *)NULL) { + fontPtr = (WinFont *)ckalloc(sizeof(WinFont)); + tkFontPtr = (TkFont *)fontPtr; + memset((VOID *)fontPtr, 0, sizeof(WinFont)); + memcpy((VOID *)&(fontPtr->font.fa), (VOID *)faPtr, + sizeof(TkFontAttributes)); + } + + fontPtr->font.asciiFontPtr = TkpGetFontFromAttributes(fontPtr->font.asciiFontPtr, tkwin, + faPtr->asciiFaPtr); + + fontPtr->font.kanjiFontPtr = TkpGetFontFromAttributes(fontPtr->font.kanjiFontPtr, tkwin, + faPtr->kanjiFaPtr); + + TkpUpdateCompoundFont((TkFont *)fontPtr, faPtr); + + return (TkFont *)fontPtr; + } + #endif /* KANJI */ + hdc = GetDC(hwnd); lf.lfHeight = -faPtr->pointsize; if (lf.lfHeight < 0) { *************** *** 170,176 **** --- 297,310 ---- if (faPtr->family == NULL) { lf.lfFaceName[0] = '\0'; } else { + #ifdef KANJI + char *nstr = TkWinConvertToNativeString(faPtr->family); + lstrcpyn(lf.lfFaceName, nstr, sizeof(lf.lfFaceName)); + if (nstr != faPtr->family) + ckfree(nstr); + #else /* KANJI */ lstrcpyn(lf.lfFaceName, faPtr->family, sizeof(lf.lfFaceName)); + #endif /* KANJI */ } ReleaseDC(hwnd, hdc); *************** *** 226,232 **** --- 360,382 ---- WinFont *fontPtr; fontPtr = (WinFont *) tkFontPtr; + #ifdef KANJI + if (Tk_FontType(tkFontPtr) == TK_FONT_COMPOUND) { + if (fontPtr->font.asciiFontPtr != NULL) { + TkpDeleteFont((TkFont *)fontPtr->font.asciiFontPtr); + } + if (fontPtr->font.kanjiFontPtr != NULL) { + TkpDeleteFont((TkFont *)fontPtr->font.kanjiFontPtr); + } + } else { + DeleteObject(fontPtr->hFont); + } + #ifdef WINFONT_DEBUG + fontPtr->isFreed = 1; + #endif /* WINFONT_DEBUG */ + #else /* KANJI */ DeleteObject(fontPtr->hFont); + #endif /* KANJI */ ckfree((char *) fontPtr); } *************** *** 278,283 **** --- 428,441 ---- Tcl_Interp *interp; interp = (Tcl_Interp *) lParam; + #ifdef KANJI + if (Tcl_KanjiCode(interp) != TCL_SJIS) { + char *istr = Tcl_ConvertToInternal(interp, elfPtr->elfLogFont.lfFaceName, NULL); + Tcl_AppendElement(interp, istr); + if (istr != elfPtr->elfLogFont.lfFaceName) + ckfree(istr); + } else + #endif /* KANJI */ Tcl_AppendElement(interp, elfPtr->elfLogFont.lfFaceName); return 1; } *************** *** 332,337 **** --- 490,500 ---- int curX, curIdx; fontPtr = (WinFont *) tkfont; + #ifdef KANJI + if (Tk_FontType(tkfont) == TK_FONT_COMPOUND) { + fontPtr = (WinFont *)fontPtr->font.asciiFontPtr; + } + #endif /* KANJI */ hdc = GetDC(fontPtr->hwnd); hFont = SelectObject(hdc, fontPtr->hFont); *************** *** 349,369 **** --- 512,578 ---- int max; int *partials; SIZE size; + #ifdef KANJI + int *mbflags; + int mi; + mbflags = (int *) ckalloc(numChars * sizeof(int)); + for (mi = 0; mi < numChars; mi++) { + if (IS_SJIS(UCHAR(source[mi]))) { + mbflags[mi] = 0; + mi++; + if (mi < numChars) + mbflags[mi] = 1; /* This is MB trail char. */ + } else { + mbflags[mi] = 0; + } + } + #endif /* KANJI */ partials = (int *) ckalloc(numChars * sizeof (int)); GetTextExtentExPoint(hdc, source, numChars, maxLength, &max, partials, &size); + #ifdef KANJI + /* On Win9X, source[max] may be a MB trail char!!! */ + if (max > 0 && max < numChars && mbflags[max]) + max--; + #endif /* KANJI */ if ((flags & TK_WHOLE_WORDS) && max < numChars) { + #ifdef KANJI + int sawBreakPoint = 0; + #endif /* KANJI */ int sawSpace; int i; sawSpace = 0; i = max; + #ifdef KANJI + while (i >= 0 && !(isascii(source[i]) && isspace(source[i]))) { + /* break at Kanji/Kana char */ + if (i > 0 && !isascii(source[i])) { + wchar wprev[2], wcur[2]; + if (mbflags[i-1]) + EncodeSJISrange(source + i - 2, wprev, 2); + else + EncodeSJISrange(source + i - 1, wprev, 1); + EncodeSJISrange(source + i, wcur, 2); + /* check kinsoku */ + if (TkpIsBreakablePoint(wprev[0], wcur[0])) { + sawBreakPoint = 1; + break; + } + } + --i; + if (i >= 0 && mbflags[i]) + --i; + } + while (i >= 0 && isascii(source[i]) && isspace(source[i])) { + #else while (i >= 0 && !isspace(source[i])) { --i; } while (i >= 0 && isspace(source[i])) { + #endif /* KANJI */ sawSpace = 1; --i; } *************** *** 379,384 **** --- 588,597 ---- max = 0; } else if (sawSpace) { max = i + 1; + #ifdef KANJI + } else if (sawBreakPoint) { + max = i; + #endif /* KANJI */ } } *************** *** 407,420 **** --- 620,646 ---- * width of the extra character. */ + #ifdef KANJI + max++; + /* the extra character may be a DB char. */ + if (max < numChars && mbflags[max]) + max++; + GetTextExtentExPoint(hdc, source, max, INT_MAX, &dummyMax, + partials, &size); + curX = partials[max-1]; + #else GetTextExtentExPoint(hdc, source, max + 1, INT_MAX, &dummyMax, partials, &size); curX = partials[max]; ++max; + #endif /* KANJI */ } ckfree((char *) partials); + #ifdef KANJI + ckfree((char *) mbflags); + #endif /* KANJI */ curIdx = max; } *************** *** 464,470 **** --- 690,703 ---- TkWinDCState state; WinFont *fontPtr; + #ifdef KANJI + fontPtr = (WinFont *) tkfont; + if (Tk_FontType(tkfont) == TK_FONT_COMPOUND) { + fontPtr = (WinFont *)fontPtr->font.asciiFontPtr; + } + #else fontPtr = (WinFont *) gc->font; + #endif /* KANJI */ display->request++; if (drawable == None) { *************** *** 553,558 **** --- 786,1068 ---- } TkWinReleaseDrawableDC(drawable, dc, &state); } + #ifdef KANJI + + /* + *--------------------------------------------------------------------------- + * + * TkpGetFailsafeFont + * + * Get the failsafe font. + * + * Results: + * Return the failsafe font. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + void + TkpGetFailsafeFont(tkfont, asciiFPtr, kanjiFPtr) + Tk_Font tkfont; + Tk_Font *asciiFPtr; + Tk_Font *kanjiFPtr; + { + TkFont *defaultF = NULL; + int tkFontType = Tk_FontType(tkfont); + /* one and only display. */ + Display *dpy = (tkDisplayList == NULL) ? NULL : tkDisplayList->display; + + if (tkFontType == TK_FONT_COMPOUND) { + /* Sounds Goooood. */ + *asciiFPtr = (Tk_Font)(((TkFont *)tkfont)->asciiFontPtr); + *kanjiFPtr = (Tk_Font)(((TkFont *)tkfont)->kanjiFontPtr); + return; + } + + *asciiFPtr = NULL; + *kanjiFPtr = NULL; + defaultF = (TkFont *)TkpGetDefaultFontByDisplay(dpy); + if (defaultF != NULL) { + int defFontType = Tk_FontType((Tk_Font)defaultF); + switch(tkFontType) { + case TK_FONT_GENERIC: { + *asciiFPtr = (Tk_Font)(((TkFont *)tkfont)->asciiFontPtr); + if (defFontType == TK_FONT_COMPOUND || defFontType == TK_FONT_2BYTES) { + /* Well, try to use kanji font in default font. */ + *kanjiFPtr = (Tk_Font)(defaultF->kanjiFontPtr); + } + break; + } + case TK_FONT_2BYTES: { + *kanjiFPtr = (Tk_Font)(((TkFont *)tkfont)->kanjiFontPtr); + *asciiFPtr = *kanjiFPtr; + break; + } + } + } else { + switch(tkFontType) { + case TK_FONT_GENERIC: { + *asciiFPtr = (Tk_Font)(((TkFont *)tkfont)->asciiFontPtr); + break; + } + case TK_FONT_2BYTES: { + *kanjiFPtr = (Tk_Font)(((TkFont *)tkfont)->kanjiFontPtr); + *asciiFPtr = *kanjiFPtr; + break; + } + } + } + if (*asciiFPtr == NULL && *kanjiFPtr == NULL) { + panic("FailsafeFont: can't get ANY font."); + } + return; + } + + #ifdef WINFONT_DEBUG + #define FailsafeFont(TK, ASC, KNJ) \ + if (((WinFont *)(TK))->isFreed == 1) { \ + panic("FailsafeFont: freed font reference."); \ + } \ + if (Tk_FontType(TK) == TK_FONT_COMPOUND) { \ + ASC = (Tk_Font)(((TkFont *)(TK))->asciiFontPtr); \ + KNJ = (Tk_Font)(((TkFont *)(TK))->kanjiFontPtr); \ + } else { \ + TkpGetFailsafeFont((TK), (&(ASC)), (&(KNJ))); \ + } + #else + #define FailsafeFont(TK, ASC, KNJ) \ + if (Tk_FontType(TK) == TK_FONT_COMPOUND) { \ + ASC = (Tk_Font)(((TkFont *)(TK))->asciiFontPtr); \ + KNJ = (Tk_Font)(((TkFont *)(TK))->kanjiFontPtr); \ + } else { \ + TkpGetFailsafeFont((TK), (&(ASC)), (&(KNJ))); \ + } + #endif /* WINFONT_DEBUG */ + + + /* + *--------------------------------------------------------------------------- + * + * Tk_MeasureWChars -- + * + * Determine the number of characters from the string that will fit + * in the given horizontal span. The measurement is done under the + * assumption that Tk_DrawWChars() will be used to actually display + * the characters. + * + * Results: + * The return value is the number of characters from source that + * fit into the span that extends from 0 to maxLength. *lengthPtr is + * filled with the x-coordinate of the right edge of the last + * character that did fit. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + int + Tk_MeasureWChars(tkfont, source, numChars, maxLength, flags, lengthPtr) + Tk_Font tkfont; /* Font in which characters will be drawn. */ + CONST wchar *source; /* Characters to be displayed. Need not be + * '\0' terminated. */ + int numChars; /* Maximum number of characters to consider + * from source string. */ + int maxLength; /* If > 0, maxLength specifies the longest + * permissible line length; don't consider any + * character that would cross this + * x-position. If <= 0, then line length is + * unbounded and the flags argument is + * ignored. */ + int flags; /* Various flag bits OR-ed together: + * TK_PARTIAL_OK means include the last char + * which only partially fit on this line. + * TK_WHOLE_WORDS means stop on a word + * boundary, if possible. + * TK_AT_LEAST_ONE means return at least one + * character even if no characters fit. */ + int *lengthPtr; /* Filled with x-location just after the + * terminating character. */ + { + CONST wchar *p; + CONST wchar *start; + int curX = 0, curIdx = 0; + int kflag; + WinFont *fontPtr; + Tk_Font asciiF; + Tk_Font kanjiF; + char *sjisbuf; + int numCharsOrg = numChars; + + if (numChars == 0) { + *lengthPtr = 0; + return 0; + } + + fontPtr = (WinFont *) tkfont; + FailsafeFont(tkfont, asciiF, kanjiF); + if (asciiF == NULL) + asciiF = kanjiF; + if (kanjiF == NULL) + kanjiF = asciiF; + + /* enough size */ + sjisbuf = ckalloc(DecodeSJISrange(source, NULL, numChars)); + + kflag = ISWKANJI(*source) | ISWKANA(*source); + for (p = start = source; ; p++, numChars--) { + if (numChars == 0 || kflag != (ISWKANJI(*p) | ISWKANA(*p))) { + int sjisChars, sjislen, sjisX; + int partlen, partChars = p - start; + + sjisChars = DecodeSJISrange(start, sjisbuf, partChars); + + sjislen = Tk_MeasureChars(kflag ? kanjiF : asciiF, sjisbuf, + sjisChars, maxLength, flags, &sjisX); + partlen = EncodeSJISrange(sjisbuf, NULL, sjislen); + + curX += sjisX; + curIdx += partlen; + if (numChars == 0) + break; + if (maxLength > 0 + && (partlen < partChars || sjisX >= maxLength)) { + break; + } + + if (flags & TK_AT_LEAST_ONE) + flags &= ~TK_AT_LEAST_ONE; + if (maxLength > 0) + maxLength -= sjisX; + kflag = ISWKANJI(*p) | ISWKANA(*p); + start = p; + } + } + + ckfree(sjisbuf); + *lengthPtr = curX; + return curIdx; + } + + /* + *--------------------------------------------------------------------------- + * + * Tk_DrawWChars -- + * + * Draw a string of characters on the screen. + * + * Results: + * None. + * + * Side effects: + * Information gets drawn on the screen. + * + *--------------------------------------------------------------------------- + */ + + void + Tk_DrawWChars(display, drawable, gc, tkfont, source, numChars, x, y) + Display *display; /* Display on which to draw. */ + Drawable drawable; /* Window or pixmap in which to draw. */ + GC gc; /* Graphics context for drawing characters. */ + Tk_Font tkfont; /* Font in which characters will be drawn; + * must be the same as font used in GC. */ + CONST wchar *source; /* Characters to be displayed. Need not be + * '\0' terminated. All Tk meta-characters + * (tabs, control characters, and newlines) + * should be stripped out of the string that + * is passed to this function. If they are + * not stripped out, they will be displayed as + * regular printing characters. */ + int numChars; /* Number of characters in string. */ + int x, y; /* Coordinates at which to place origin of + * string when drawing. */ + { + CONST wchar *p; + CONST wchar *start; + int kflag; + WinFont *fontPtr; + Tk_Font asciiF; + Tk_Font kanjiF; + char *sjisbuf; + + fontPtr = (WinFont *) tkfont; + FailsafeFont(tkfont, asciiF, kanjiF); + if (asciiF == NULL) + asciiF = kanjiF; + if (kanjiF == NULL) + kanjiF = asciiF; + + /* enough size */ + sjisbuf = ckalloc(DecodeSJISrange(source, NULL, numChars)); + + kflag = ISWKANJI(*source) | ISWKANA(*source); + for (p = start = source; ; p++, numChars--) { + if (numChars == 0 || kflag != (ISWKANJI(*p) | ISWKANA(*p))) { + int sjisChars, sjisX; + int partChars = p - start; + + sjisChars = DecodeSJISrange(start, sjisbuf, partChars); + + Tk_DrawChars(display, drawable, gc, kflag ? kanjiF : asciiF, + sjisbuf, sjisChars, x, y); + (void)Tk_MeasureChars(kflag ? kanjiF : asciiF, sjisbuf, + sjisChars, 0, 0, &sjisX); + x += sjisX; + + if (numChars == 0) + break; + + kflag = ISWKANJI(*p) | ISWKANA(*p); + start = p; + } + } + + ckfree(sjisbuf); + } + #endif /* KANJI */ /* *--------------------------------------------------------------------------- *************** *** 597,605 **** --- 1107,1128 ---- if (tkFontPtr != NULL) { fontPtr = (WinFont *) tkFontPtr; + #ifdef KANJI + #ifdef WINFONT_DEBUG + if (fontPtr->isFreed == 1) { + panic("AllocFont: freed font reference."); + } + #endif /* WINFONT_DEBUG */ + if (Tk_FontType(tkFontPtr) == TK_FONT_COMPOUND) { + return tkFontPtr; + } + #endif DeleteObject(fontPtr->hFont); } else { fontPtr = (WinFont *) ckalloc(sizeof(WinFont)); + #ifdef KANJI + memset((VOID *)fontPtr, 0, sizeof(WinFont)); + #endif /* KANJI */ } window = Tk_WindowId(((TkWindow *) tkwin)->mainPtr->winPtr); *************** *** 621,631 **** --- 1144,1199 ---- faPtr->slant = (tm.tmItalic != 0) ? TK_FS_ITALIC : TK_FS_ROMAN; faPtr->underline = (tm.tmUnderlined != 0) ? 1 : 0; faPtr->overstrike = (tm.tmStruckOut != 0) ? 1 : 0; + #ifdef KANJI + faPtr->setwidth = TK_SW_NORMAL; + faPtr->foundry = NULL; + faPtr->charset = (tm.tmCharSet == SHIFTJIS_CHARSET) ? "shiftjis" : "default"; + faPtr->fontType = + (tm.tmCharSet == SHIFTJIS_CHARSET) ? TK_FONT_2BYTES : TK_FONT_GENERIC; + faPtr->asciiFontName = NULL; + faPtr->kanjiFontName = NULL; + faPtr->pointAdjust = 0.0; + #endif fontPtr->font.fm.ascent = tm.tmAscent; fontPtr->font.fm.descent = tm.tmDescent; fontPtr->font.fm.maxWidth = tm.tmMaxCharWidth; fontPtr->font.fm.fixed = !(tm.tmPitchAndFamily & TMPF_FIXED_PITCH); + #ifdef KANJI + if (Tk_FontType(fontPtr) == TK_FONT_GENERIC) { + fontPtr->font.asciiFontPtr = (TkFont *)fontPtr; + fontPtr->font.kanjiFontPtr = NULL; + } else { + fontPtr->font.asciiFontPtr = NULL; + fontPtr->font.kanjiFontPtr = (TkFont *)fontPtr; + } + + /* + * Get information used for drawing underlines in generic code on a + * non-underlined font. (see last "#ifdef KANJI" in GetFontFronObj()) + */ + + fontPtr->font.underlinePos = fontPtr->font.fm.descent / 2; + fontPtr->font.underlineHeight = fontPtr->font.fa.pointsize / 10; + if (fontPtr->font.underlineHeight == 0) { + fontPtr->font.underlineHeight = 1; + } + if (fontPtr->font.underlinePos + fontPtr->font.underlineHeight > + fontPtr->font.fm.descent) { + /* + * If this set of values would cause the bottom of the underline + * bar to stick below the descent of the font, jack the underline + * up a bit higher. + */ + + fontPtr->font.underlineHeight = + fontPtr->font.fm.descent - fontPtr->font.underlinePos; + if (fontPtr->font.underlineHeight == 0) { + fontPtr->font.underlinePos--; + fontPtr->font.underlineHeight = 1; + } + } + #endif hFont = SelectObject(hdc, hFont); ReleaseDC(hwnd, hdc); *************** *** 636,638 **** --- 1204,1287 ---- return (TkFont *) fontPtr; } + #ifdef KANJI + + void + TkpUpdateCompoundFont(tkFontPtr, faPtr) + TkFont *tkFontPtr; + CONST TkFontAttributes *faPtr; + { + WinFont *fontPtr = (WinFont *)tkFontPtr; + WinFont *ascii = (WinFont *)fontPtr->font.asciiFontPtr; + WinFont *kanji = (WinFont *)fontPtr->font.kanjiFontPtr; + int underlinePos, barHeight, overHeight; + + if (ascii == (WinFont *)NULL) { + panic("ascii font NULL."); + } + if (kanji == NULL) { + panic("kanji font NULL."); + } + + if (ascii->font.tabWidth > kanji->font.tabWidth) { + fontPtr->font.tabWidth = ascii->font.tabWidth; + } else { + fontPtr->font.tabWidth = kanji->font.tabWidth; + } + + if (ascii->font.fm.ascent > kanji->font.fm.ascent) { + fontPtr->font.fm.ascent = ascii->font.fm.ascent; + } else { + fontPtr->font.fm.ascent = kanji->font.fm.ascent; + } + + if (ascii->font.fm.descent > kanji->font.fm.descent) { + fontPtr->font.fm.descent = ascii->font.fm.descent; + underlinePos = kanji->font.fm.descent; + } else { + fontPtr->font.fm.descent = kanji->font.fm.descent; + underlinePos = ascii->font.fm.descent; + } + underlinePos++; + if (underlinePos >= fontPtr->font.fm.descent) { + underlinePos = fontPtr->font.fm.descent - 1; + } + if (underlinePos < 1) { + underlinePos = 1; + } + barHeight = ABS(fontPtr->font.fm.descent - underlinePos); + overHeight = (fontPtr->font.fm.descent + fontPtr->font.fm.ascent) / 10; + if (barHeight > overHeight) { + barHeight = overHeight; + } + + if (ascii->font.fm.maxWidth > kanji->font.fm.maxWidth) { + fontPtr->font.fm.maxWidth = ascii->font.fm.maxWidth; + } else { + fontPtr->font.fm.maxWidth = kanji->font.fm.maxWidth; + } + + if (ascii->font.fm.fixed != 0 && kanji->font.fm.fixed != 0) { + fontPtr->font.fm.fixed = kanji->font.fm.fixed; + } + + fontPtr->font.underlinePos = underlinePos; + fontPtr->font.underlineHeight = barHeight; + + if (faPtr != NULL) { + fontPtr->font.fa.underline = faPtr->underline; + fontPtr->font.fa.overstrike = faPtr->overstrike; + fontPtr->font.fa.pointAdjust = faPtr->pointAdjust; + } + } + + #ifdef IME_AWARE + HFONT + Tk_GetHFONT(tkfont) + Tk_Font tkfont; + { + WinFont *fontPtr = (WinFont *)tkfont; + return fontPtr->hFont; + } + #endif /* IME_AWARE */ + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinInit.c ./win/tkWinInit.c *** ../../tk8.0.5/win/tkWinInit.c Tue Sep 15 03:24:00 1998 --- ./win/tkWinInit.c Fri Mar 12 00:39:43 1999 *************** *** 43,48 **** --- 43,56 ---- TkpInit(interp) Tcl_Interp *interp; { + #ifdef KANJI + Tk_Window mWin = Tk_MainWindow(interp); + if (TkpDefaultFontPkgInit(mWin)) { + if (Tcl_Eval(interp, "font failsafe defaultgui") != TCL_OK) { + panic("Can't set failsafe font."); + } + } + #endif /* KANJI */ return Tcl_Eval(interp, initScript); } *************** *** 119,121 **** --- 127,152 ---- MessageBox(NULL, msg, title, MB_OK | MB_ICONEXCLAMATION | MB_SYSTEMMODAL | MB_SETFOREGROUND | MB_TOPMOST); } + #ifdef KANJI + + char * + TkWinConvertToNativeString(str) + char *str; + { + int kanjiCode; + wchar *wstr; + char *sstr; + + if (Tcl_KanjiString(NULL, str, NULL, &kanjiCode) == TCL_NOT_KANJI + || kanjiCode == TCL_SJIS) { + return str; + } else { + wstr = (wchar *)ckalloc((Tcl_KanjiEncode(kanjiCode, str, NULL) + 1) * sizeof(wchar)); + Tcl_KanjiEncode(kanjiCode, str, wstr); + sstr = ckalloc(Tcl_KanjiDecode(TCL_SJIS, wstr, NULL) + 1); + Tcl_KanjiDecode(TCL_SJIS, wstr, sstr); + ckfree((char *)wstr); + } + return sstr; + } + #endif /* KANJI */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinInt.h ./win/tkWinInt.h *** ../../tk8.0.5/win/tkWinInt.h Fri Feb 5 06:01:35 1999 --- ./win/tkWinInt.h Fri Mar 12 00:39:43 1999 *************** *** 190,195 **** --- 190,198 ---- TkWindow *winPtr, HWND hwnd)); extern void TkWinXCleanup _ANSI_ARGS_((HINSTANCE hInstance)); extern void TkWinXInit _ANSI_ARGS_((HINSTANCE hInstance)); + #ifdef KANJI + extern char * TkWinConvertToNativeString _ANSI_ARGS_((char *str)); + #endif /* KANJI */ #endif /* _TKWININT */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinMenu.c ./win/tkWinMenu.c *** ../../tk8.0.5/win/tkWinMenu.c Fri Feb 5 06:44:18 1999 --- ./win/tkWinMenu.c Fri Mar 12 00:39:44 1999 *************** *** 427,432 **** --- 427,435 ---- TkMenuEntry *mePtr; /* A pointer to the menu entry. */ { char *itemText; + #ifdef TK_KANJI_OK + wchar *itemWText; + #endif /* TK_KANJI_OK */ if (mePtr->type == TEAROFF_ENTRY) { itemText = ckalloc(sizeof("(Tear-off)")); *************** *** 474,479 **** --- 477,515 ---- } } + #ifdef TK_KANJI_OK + itemWText = (wchar*)ckalloc(size * sizeof(wchar)); + + if (mePtr->labelLength == 0) { + itemWText[0] = 0; + } else { + for (i = 0, j = 0; i < mePtr->labelLength; i++, j++) { + if (mePtr->label[i] == '&') { + itemWText[j++] = '&'; + } + if (i == mePtr->underline) { + itemWText[j++] = '&'; + } + itemWText[j] = mePtr->label[i]; + } + itemWText[j] = '\0'; + } + + if (mePtr->accelLength > 0) { + j = Tcl_WStrlen(itemWText); + itemWText[j++] = '\t'; + for (i = 0; i < mePtr->accelLength; i++, j++) { + if (mePtr->accel[i] == '&') { + itemWText[j++] = '&'; + } + itemWText[j] = mePtr->accel[i]; + } + itemWText[j] = '\0'; + } + itemText = ckalloc(Tcl_DecodeSJIS(itemWText, NULL) + 1); + Tcl_DecodeSJIS(itemWText, itemText); + ckfree((char*)itemWText); + #else itemText = ckalloc(size); if (mePtr->labelLength == 0) { *************** *** 502,507 **** --- 538,544 ---- } itemText[j] = '\0'; } + #endif /* TK_KANJI_OK */ } return itemText; } *************** *** 2303,2309 **** --- 2340,2353 ---- */ Tk_GetFontMetrics(menuPtr->tkfont, &menuMetrics); + #ifdef TK_KANJI_OK + { + wchar wTmp = 'M'; + accelSpace = Tk_TextWidth(menuPtr->tkfont, &wTmp, 1); + } + #else accelSpace = Tk_TextWidth(menuPtr->tkfont, "M", 1); + #endif /* TK_KANJI_OK */ for (i = 0; i < menuPtr->numEntries; i++) { tkfont = menuPtr->entries[i]->tkfont; diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinWm.c ./win/tkWinWm.c *** ../../tk8.0.5/win/tkWinWm.c Fri Feb 5 06:01:46 1999 --- ./win/tkWinWm.c Fri Mar 12 00:39:47 1999 *************** *** 644,649 **** --- 644,652 ---- HWND child = TkWinGetHWND(winPtr->window); int x, y, width, height, state; WINDOWPLACEMENT place; + #ifdef KANJI + char *nstr; + #endif /* KANJI */ parentHWND = NULL; child = TkWinGetHWND(winPtr->window); *************** *** 721,730 **** --- 724,743 ---- */ createWindow = winPtr; + #ifdef KANJI + nstr = TkWinConvertToNativeString(wmPtr->titleUid); + wmPtr->wrapper = CreateWindowEx(wmPtr->exStyle, + TK_WIN_TOPLEVEL_CLASS_NAME, + nstr, wmPtr->style, x, y, width, height, + parentHWND, NULL, Tk_GetHINSTANCE(), NULL); + if (nstr != wmPtr->titleUid) + ckfree(nstr); + #else /* KANJI */ wmPtr->wrapper = CreateWindowEx(wmPtr->exStyle, TK_WIN_TOPLEVEL_CLASS_NAME, wmPtr->titleUid, wmPtr->style, x, y, width, height, parentHWND, NULL, Tk_GetHINSTANCE(), NULL); + #endif /* KANJI */ SetWindowLong(wmPtr->wrapper, GWL_USERDATA, (LONG) winPtr); createWindow = NULL; *************** *** 2011,2017 **** --- 2024,2037 ---- } else { wmPtr->titleUid = Tk_GetUid(argv[3]); if (!(wmPtr->flags & WM_NEVER_MAPPED) && wmPtr->wrapper != NULL) { + #ifdef KANJI + char *nstr = TkWinConvertToNativeString(wmPtr->titleUid); + SetWindowText(wmPtr->wrapper, nstr); + if (nstr != wmPtr->titleUid) + ckfree(nstr); + #else /* KANJI */ SetWindowText(wmPtr->wrapper, wmPtr->titleUid); + #endif /* KANJI */ } } } else if ((c == 't') && (strncmp(argv[1], "transient", length) == 0) diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/tkWinX.c ./win/tkWinX.c *** ../../tk8.0.5/win/tkWinX.c Sat Oct 10 09:30:37 1998 --- ./win/tkWinX.c Mon Mar 15 14:08:21 1999 *************** *** 20,26 **** --- 20,35 ---- * The zmouse.h file includes the definition for WM_MOUSEWHEEL. */ + #ifdef BUGFIX + #if defined(_MSC_VER) && _MSC_VER >= 1100 #include + #endif /* _MSC_VER */ + #ifndef WM_MOUSEWHEEL + #define WM_MOUSEWHEEL 0x20A + #endif /* !WM_MOUSEWHEEL */ + #else + #include + #endif /* BUGFIX */ /* * Definitions of extern variables supplied by this file. *************** *** 49,54 **** --- 58,66 ---- static unsigned int GetState _ANSI_ARGS_((UINT message, WPARAM wParam, LPARAM lParam)); static void GetTranslatedKey _ANSI_ARGS_((XKeyEvent *xkey)); + #if defined(KANJI) && defined(IME_AWARE) + static void ConfigureIMEComposition _ANSI_ARGS_((HWND hwnd)); + #endif /* KANJI && IME_AWARE */ /* *---------------------------------------------------------------------- *************** *** 504,509 **** --- 516,527 ---- result = TkWinEmbeddedEventProc(hwnd, message, wParam, lParam); break; + #if defined(KANJI) && defined(IME_AWARE) + case WM_IME_STARTCOMPOSITION: + result = DefWindowProc(hwnd, message, wParam, lParam); + ConfigureIMEComposition(hwnd); + break; + #endif /* KANJI && IME_AWARE */ default: if (!Tk_TranslateWinEvent(hwnd, message, wParam, lParam, &result)) { *************** *** 594,599 **** --- 612,620 ---- case WM_KILLFOCUS: case WM_DESTROYCLIPBOARD: case WM_CHAR: + #ifdef KANJI + case WM_IME_CHAR: + #endif case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: *************** *** 705,711 **** Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD"); event.xselectionclear.time = TkpGetMS(); break; ! case WM_MOUSEWHEEL: /* * The mouse wheel event is closer to a key event than a --- 726,732 ---- Tk_InternAtom((Tk_Window)winPtr, "CLIPBOARD"); event.xselectionclear.time = TkpGetMS(); break; ! case WM_MOUSEWHEEL: /* * The mouse wheel event is closer to a key event than a *************** *** 714,719 **** --- 735,743 ---- */ case WM_CHAR: + #ifdef KANJI + case WM_IME_CHAR: + #endif case WM_SYSKEYDOWN: case WM_SYSKEYUP: case WM_KEYDOWN: *************** *** 811,816 **** --- 835,861 ---- Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); event.type = KeyRelease; break; + #ifdef KANJI + case WM_IME_CHAR: + /* + * Synthesize both a KeyPress and a KeyRelease. + */ + + event.type = KeyPress; + event.xany.send_event = -1; + event.xkey.keycode = 0; + if (wParam>>8 != 0) { + event.xkey.nchars = 2; + event.xkey.trans_chars[0] = (TCHAR) (wParam>>8); + event.xkey.trans_chars[1] = (TCHAR) wParam; + } else { + event.xkey.nchars = 1; + event.xkey.trans_chars[0] = (TCHAR) wParam; + } + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.type = KeyRelease; + break; + #endif /* KANJI */ } break; } *************** *** 1059,1061 **** --- 1104,1197 ---- { return GetCurrentTime(); } + + #if defined(KANJI) && defined(IME_AWARE) + + static void + ConfigureIMEComposition(hwnd) + HWND hwnd; + { + /* set composition window placement */ + TkWindow *winPtr = (TkWindow *) Tk_HWNDToWindow(hwnd); + Tk_Window focusPtr = (Tk_Window)TkGetFocusWin(winPtr); + + if (focusPtr) { + HWND hwndFocus = Tk_GetHWND(Tk_WindowId(focusPtr)); + HIMC hIMC = ImmGetContext(hwnd); + COMPOSITIONFORM form; + int xpos, ypos, left, top; + + Tk_GetRootCoords(focusPtr, &left, &top); + Tk_GetRootCoords((Tk_Window)winPtr, &xpos, &ypos); + left -= xpos; + top -= ypos; + /* default: at bottom of a focused widget. */ + xpos = left; + ypos = top + Tk_Height(focusPtr); + + if (Tk_Class(focusPtr) == Tk_GetUid("Entry") || + Tk_Class(focusPtr) == Tk_GetUid("Text")) { + Tcl_Interp *interp = winPtr->mainPtr->interp; + int argc; + char **argv; + /* Entry/Text: near the insertion cursor. */ + if (Tcl_VarEval(interp, Tk_PathName(focusPtr), " xypos insert", + NULL) == TCL_OK && + Tcl_SplitList(interp, Tcl_GetStringResult(interp), + &argc, &argv) == TCL_OK && + argc == 2 && + Tcl_GetInt(interp, argv[0], &xpos) == TCL_OK && + Tcl_GetInt(interp, argv[1], &ypos) == TCL_OK) { + LOGFONT lf; + TEXTMETRIC tm; + HDC hdc; + Tk_Font tkfont; + + /* get IME logfont */ + ImmGetCompositionFont(hIMC, &lf); + + /* get widget font */ + if (Tcl_VarEval(interp, Tk_PathName(focusPtr), " cget -font", + NULL) == TCL_OK && + (tkfont = Tk_GetFontFromObj(interp, focusPtr, + Tcl_GetObjResult(interp))) + != NULL) { + LOGFONT tmplf; + HFONT hFont; + Tk_Font ascii, kanji; + TkpGetFailsafeFont(tkfont, &ascii, &kanji); + if (kanji != NULL) { + hFont = Tk_GetHFONT(kanji); + } else { + hFont = Tk_GetHFONT(tkfont); + } + GetObject(hFont, sizeof(LOGFONT), &tmplf); + Tk_FreeFont(tkfont); + + /* set height of the composition font */ + lf.lfHeight = tmplf.lfHeight; + lf.lfWidth = 0; + ImmSetCompositionFont(hIMC, &lf); + /* get IME logfont again */ + ImmGetCompositionFont(hIMC, &lf); + } + + /* get metrics of the IME font */ + hdc = GetDC(hwndFocus); + SelectObject(hdc, CreateFontIndirect(&lf)); + GetTextMetrics(hdc, &tm); + ReleaseDC(hwndFocus, hdc); + + xpos += left; + ypos += top; + ypos -= tm.tmAscent; + } + } + form.dwStyle = CFS_POINT; + form.ptCurrentPos.x = xpos; + form.ptCurrentPos.y = ypos; + ImmSetCompositionWindow(hIMC, &form); + ImmReleaseContext(hwnd, hIMC); + } + } + #endif /* KANJI && IME_AWARE */ diff -r -c -P -x CVS -I .*\$Id: .* Exp \$ ../../tk8.0.5/win/winMain.c ./win/winMain.c *** ../../tk8.0.5/win/winMain.c Fri Feb 5 05:57:18 1999 --- ./win/winMain.c Fri Mar 12 00:39:48 1999 *************** *** 102,112 **** --- 102,117 ---- GetModuleFileName(NULL, buffer, sizeof(buffer)); argv[0] = buffer; + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + for (p = Tcl_KStrchr(buffer, '\\'); p != NULL; p = Tcl_KStrchr(p, '\\')) + *p = '/'; + #else for (p = buffer; *p != '\0'; p++) { if (*p == '\\') { *p = '/'; } } + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ Tk_Main(argc, argv, Tcl_AppInit); return 1; *************** *** 238,243 **** --- 243,252 ---- char *cmdLine, *p, *arg, *argSpace; char **argv; int argc, size, inquote, copy, slashes; + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + char *pend; + int klen; + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ cmdLine = GetCommandLine(); *************** *** 265,273 **** --- 274,289 ---- size--; p = cmdLine; + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + pend = p + strlen(p); + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ for (argc = 0; argc < size; argc++) { argv[argc] = arg = argSpace; + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + while (isspace((unsigned char)*p)) { + #else while (isspace(*p)) { + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ p++; } if (*p == '\0') { *************** *** 301,314 **** --- 317,345 ---- slashes--; } + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + if ((*p == '\0') || (!inquote && isspace((unsigned char)*p))) { + #else if ((*p == '\0') || (!inquote && isspace(*p))) { + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ break; } + #if defined(KANJI) && defined(HANDLE_KANJI_PATHNAME) + klen = Tcl_KanjiLength(p, pend, TCL_SJIS); + if (klen == 0) + klen = 1; + if (copy) { + memcpy((VOID *)arg, (VOID *)p, klen); + arg += klen; + } + p += klen; + #else if (copy != 0) { *arg = *p; arg++; } p++; + #endif /* KANJI && HANDLE_KANJI_PATHNAME */ } *arg = '\0'; argSpace = arg + 1;