unsigned - みる会図書館


検索対象: 月刊 C MAGAZINE 1990年10月号
26件見つかりました。

1. 月刊 C MAGAZINE 1990年10月号

ControIIine ーンの数 ) , そして black と white の色 ( これ らを境界色および背景色として使うが , と くに黒と白て、なくてもよい ) が決ったら , ウ インドウを作ることがて、きます。ウインド ウを作るもっとやさしい方法はほかにもあ りますが , 本稿の方法だと , ウインドウか ら確実にカラーにアクセスて、きます。 ソースコードの main ( ) 関数の中て、は , / * ウインドウを作り ICCCM の値 をセットする * / SetUpWindow( display, visual, depth, colormap, black, white, &window ) : I C C C M は , I n t e r ー C 1 i e n t C 0 m municaitons Conventions Manual ( クラ イアント間通信規約マニュアル ) の頭文字て、 す。この文書は , X のアプリケーションの正 こて、は単純 しい動作を規定しています。 化のため , ICCCM のすべての値は設定して いませんが , ほとんどの場合はこれて、十分 て、 , window manager からの苦情はてない と思います。 SetUpWindow( ) 関数は , 私たち用のウィ ンドウを作ります。最初に , ウインドウの サイズと位置を決めます。 X て、は , 通常 , geometry specification と呼ばれるコマンド 行バラメータを渡します。 -geometry widthXheight 十 x 十 y これて , ウインドウの位置とサイズを指 定します (width, height,x,y は数値て、 ,width の後にスペースはない ) 。 X のプログラムの ほとんどが , この方法によってアプリケー ションのウインドウの位置を決めます。 次は , XSetWindowAttributes 構造体の一 部に値を入れます 0XGetVisuallnfo( ) 関数の 場合のように , 構造体の一部に値を入れて から , どの部分に値を入れたかをビットマ スクて XIib のルーチンに教えます。 XSetWindowAttributes 構造体の完全な姿 を , List 8 に示します。そのほとんどのフィ ールドに , 私たちは List 9 に示すデフォルト の値を使います。 event mask フィールドは , 私たちが ButtonPress イベント ( ューザがウインドウ 25 : i f ( 32 CM AGAZIN E 19 10 List 8 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10 : 14 : 17 : List 9 1 : 2 : 3 : 4 : 6 : 7 : 8 : 9 : typedef struct{ XSetW indowAttr i butes : Cursor cursor; Colormap colormap; B00 ー override_redirect; long do_not_propagate_mask; long event-mask; B00 1 save_under : / * リクエストするだけ * / unsigned long backing_pixel; unsigned long backing_planes; int backing-store; / * リクエストするだけ * / int win_gravity; int bit_gravity; unsigned long border_pixel; Pixmap border-pixmap; unsigned long background-pixel : Pixmap background_pixmap; attribute_mask = CWBackPixel ー CWBorderPixel ー CWEventMask ー CWCoIormap; colormap; attributes. colormap attributes. event_mask ExposureMask ー ButtonPressMask; attributes. border-pixel fore : /*"black" の色 */ 5 : attributes. background-pixel = back; /*"white" の色 */ XSetWindowAttributes attributes; unsigned long attribute-mask; unsigned long back, fore; Colormap colormap; List 1 0 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10 : 12 : 13 : 15 : 16 : 20 : 22 : 23 : 24 : 26 : 1 : DispIay *display; int screen; W indow parent : i nt x, y : unsigned int width, unsigned int border int depth; unsigned int class; v i sua 1 *V i sua 1 : height; ⅵ dth : / * 32 , 圓 0 以内 * / / * カラー・プレーンの数 * / / * われわれが探素したもの * / unsigned long attribute-mask; 11 : XSetWindowAttributes attributes : = DefaultScreen( display ) : screen = R00tWindow( display, screen ) : parent 14 : border_width / * 幅 2 ピクセル * / class InputOutput; / * または Input0nly, XCreateWindow( display, W indow または CopyFromPärent*/ window / * 、エラ parent, x, Y, width, height, border_width; depth, class, (Window)None ) { &attributes ) : attribute_mask, v i sua l, / * われわれの v i sua は /

2. 月刊 C MAGAZINE 1990年10月号

PT C (signed int)C ・ 算術演算子 十一 & 十一 & ところが , BSD ( および UNIX との互換性 を考慮した多くの処理系 ) て、は , 上記て、定義 されている値保持規則て、はなく , unsigned 型はつねに unsigned int 型に拡張されるとい う規則が採用されています。このため以下 のようなプログラム例て、は異なる結果が引 き起こされる場合があります。 #include <STDIO. H> く = くく main( ) unsigned Char C ; 句読点 c=getchar( ) : if(c ー @ ' く 0) puts( "LO" ) ; else puts( " 印 " ) ; このプログラムを MS ー C て、コンパイルして 実行すると , キーポードからネ@″よりア スキーコードの小さい文字が入力された場 合は、、 LO 〃が , 大きい文字が入力された場 合は、、 HI 〃が表示れます。ところが , 同じ プログラムを QuickC て、コンパイルして実行 すると , つねに、、 HI 〃が表示され , "LO" が表示されることはありません。 また , 2 項演算子を使用して異なるデータ タイプの演算を行う場合には , 以下のよう な拡張規則により両方の値が同じデータタ イプに変換されます。 if(A = = LongDouble ー = LongDouble) 空白 水平タブ 垂直タブ 空白 注釈 文字 注釈 プロジェクト PragmaC 53

3. 月刊 C MAGAZINE 1990年10月号

標準入力から文字列 ( ファイルの終わりの前 , または \ n の前まで ) を読み込み , 格納する ③についてもう少し説明しましよう。ど のストリームと結合したかは戻り値として 得られます。具体的には , ストリームを制 御する変数へのポインタが返ってきます。 ただし , ファイルのオープンに失敗したら マクロ名 getchar ・機能指定されたファイルから 1 文字読み込むマクロ NULL が返ってきます。 具体例を挙げましよう (List 1 ) 。この例て、 ルをクローズする関数が fclose 関数て、す。 する変数へのポインタ ) を受け取り , ファイ という情報 ( クローズするストリームを制御 また , 「どのストリームをクローズするか」 は , これは , たとえば構造体として次のように いう変数は日 LE 型として宣言されています。 て f ⅱ el という変数に代入しています。 f ⅱ el と トリームを制御する変数へのポインタ ) を得 ムと結合しているかという情報 ( すなわちス オープンしています。そしてどのストリー w(write) モードで , myf ⅱ e. xyz という名のファイルを ・形式 ・機能 関数名 ・形式 ・機能 関数名 ・形式 ・機能 関数名 ・形式 ・機能 関数名 ・形式 ・機能 int getchar(void) , 標準入力から 1 文字読み込むマクロ。 getc(stdin) と同じ char * gets(char *Str) , gets int fgetc(FILE * stream) , fgetc getc とまったく同じ働きをする。こちらはマクロでなく実際の関数呼び出し fgets ( ¥ N は格納されない ) み出す ) 際には , 押し戻されたのと逆順に返される 文字 c を unsigned cha 「に変換し , 入力ストリームに押し戻す (push-back)o 再び取り出す ( 読 int ungetc(int c, FILE *stream) , ungetc 入力ファイルから , 長さ max ⅱ ne 未満の文字を読み込み , 格納する ( ¥ N も格納される ) char *fgets(char *Str, int maxline, FILE *stream) , 定義されています。 typedef struct unsigned unsigned unsigned signed signed signed unsigned unsigned signed } FILE ; Char Char int int Char Char int int *fpi : *bptr ; flags ; blevel• bsize ; fd ; ho ; istemp token ; 3 ファイルへの出力 マクロ名 putc ・形式 int putc(int c, FILE *stream) , ・機能指定されたファイルに 1 文字書き込むマクロ マクロ名 putchar ・形式 ・機能 関数名 ・形式 ・機能 関数名 ・形式 ・機能 関数名 ・形式 ・機能 int putchar(int c) , 標準出力に 1 文字書き込むマクロ。 putc((c), stdout) と同じ fputc int fputc(int c, FILE * st 「 eam) , putc とまったく同じ働きをする関数 putS int puts(const char * str) , 標準出力に文字列を書き込む。その際出力に改行文字を付け加える 出力ファイルに文字列を書き込む int fputs(const char * str, FILE * st 「 eam) , fputs これについては必ずしも構造体て、定義さ れているとは限らず , またメンバの数や機 能についてもこのとおりとは限りません。 イメージとして捉えてください。それて、も , ファイルの上て、の位置 , ファイルの状態 , バッフアの状態を表す情報をまとめて FILE 型という変数型が定義されています。そし てこの日 LE 型こそがストリームを制御する 134 CMAGAZINE 19 10 要な情報て、ある , モードについて話しまし さて , ファイルをオープンするときに必 変数の型となっているわけて、す。 ために必要なすべての情報を記録している 4 書式つき入出力 関数名 ・形式 ・機能 関数名 scanf int scanf(const char * format, argl, arg2, 標準入力からの文字列を入力書式制御にしたがって変換し , 変数に値を格納する fscanf

4. 月刊 C MAGAZINE 1990年10月号

サプメニューから選択された番号からコマ どちらの領域に何をするのかを決定する をマッピングし , データの読み書きを行い ンド番号を生成します。入力した値は関数 ために , はじめにメニュー選択を行います。 ます。 3 以外は再 まず , スケジュールかメモか , あるいは完 st 「 ch 「を利用してヾ 1 〃 , 入力するような単項目チェックをしていま 全に終了するために EMS 領域を解放するの かを決定します。次にデータを書き込むの す。 か , 読み出すのか , 削除するのかを決定し することが決まったら , EMS のセットア まず , メニューて、すが , Table 1 のように ップを行います。関数 setup( ) て、は , EMM ます。 なっています。関数 menu ( ) て、はメニューと のイニシャライズ em rn init( ) , マッピング 行為が決定されたら , 該当する EMS 領域 処理詳細 List 1 List 1 0 ー 8 0 ・ ) 0 , 1 ワ 3 っ 0 -4 ・ -. 0 ( し行ー 8 0 リ 0 1 よっ 0 一 4 ・ 0 ^ 0 0 ー 8 0 11 ワ 0 っ 0 -4- 尸 0 れ 0 7 ー 8 0 1 人っ乙っーな・ 0 ^. 0 っー 8 0 ・ ) 0 1 よワ〕っ 0 4 ・ LO れ 0 0 ー 8 0 11 っ乙 LD - -0 LO ^. 0 ^ 0 ^ 0 《し《 0 CD 《 0 ^ 0 ーー行ー行ー - - 行ー行ー行ー行ーウーっー 8 8 8 8 8 8 8 8 8 8 0 》 0 ・》 0 ) 0 ) 0 リ 0 0 0 0 0 0 0 0 0 0 11 11 1 よ 1 ー人 1- よ・ー人・ー・ 1 ー - , ーよ、ー 1 ー 4 1 ー・ 1 ・人 1- よ 1 ー画 , ーよ unsigned emm handle, ppages; char bufC256] : cmd ニ menu() : setup( &emm_handle, &ppages ) : f i nd / * E M S の解放 * / i f ( cmd if ( find = NG ) { pr intf ( " E M S ハンドルを取得できませんでした。 Yn ” ) : ex i t ( 1 ) : / * E M S の解放 * / else if ( free-pages( emm-handle ) printf ( " 拡張メモリを解放できませんでした . Yn" ) : ex i t ( 1 ) : printf( "Removed. Yn" ) : return( 0 ) : 1 : # i ncl ude く std i 0. h > 2 : # i ncl ud e く con i 0. h 〉 3 : #include く dos. h> 4 : #include く process. h 〉 5 : #include く string. h> 7 : / * 関数プロトタイプ * / 8 = #include " 0Yi00. h ! 9 : int menu( void ) 10 : int setup( unsigned * , unsigned * ) : i nt em m- i n i t ( VO i d ) : 12 : int get_pages( unsigned, unsigned * ) : 13 : vo i d co I or ( i nt ) : 14 : 15 : / * グローバル変数 * / 16 : union REGS Regs ; 17 : struct SREGS Segs; Emm-nameC9] 18 : char Version[8] : 20 : / * Physical Address Array * / 21 : struct paa { unsigned pseg;/* Page Segment * / 22 : uns igned pnum;/* Page Number * / 23 : 24 : } far Pa[4] : 25 : 26 : 27 : typedef struct schedule { char date[10] : 28 : char time[10]; 29 : char memo[60] : 30 : } ScheduIe : 31 : 32 : 33 : typedef struct note { char titIeC20]; 34 : char memo[60] : 35 : 36 : } Note; 37 : 38 : 39 : ℃ har far name[9] "C-magaYOY0" 40 : ScheduIe far *ems-areal ; 41 : Note far *ems_area2; 42 : char *mn1[3] ” 1 . スケジュール " 43 : ” 2 . メモ” 44 : " 3 . 終了 ( ェリア解放 ) " 45 : 46 : } : 47 : char *mn2[3] ” 1 . 登録” , 48 : " 2 . 参照” , 49 : ” 3 . 削除” 50 : 52 : 53 : 54 : i nt ma i n ( vo i d ) 56 : int find, cmd, typ; ” EMMXXXXO ” , if ( find = NG ) { / * ページのアロケート * / if ( get-pages( 2 , &emm-handle ) ex i t ( 1 ) : if ( set_emm_name ( emm_handle, name ) / * E M S の解放 * / free-pages( emm-handle ) : ex i t ( 1 ) : / * ハンドルページのマップ * / ( cmd ー tYP = mapping( emm-handle, Pa[0]. pnum, typ ) : i f ( typ ( ScheduIe far * ) ( Pa[0] . pseg * 0X10000 し ) : ems_areal e I s e i f ( typ ( Note far * ) ( Pa[0] . pseg * 0X10000 し ) ; ems area2 sw i tch ( cmd ) { case 1 : / * スケジュール登録 * / printf( ”く date> gets( buf ) : strncpy ( ems-areal->date, buf, 10 ) : printf( ”く time> gets( buf ) ; strncpy( ems-areal->time, buf, 10 ) : printf( " く memo>" ) : gets( buf ) : strncpy ( ems-areal->memo, buf, 60 ) : break ; case 2 : / * スケジュール参照 * / strncpy ( buf, ems_areal->date, 10 ) : ワンポイントプログラミング講座 123

5. 月刊 C MAGAZINE 1990年10月号

PragmaC ノヾックグラウンド ランゲージだろうカ : かしたら , PragmaC が私にとって C 言語て、 : はめになるだろうという予感がある。もし はっきりいえば , 近い将来必ず逃げ出す : 私個人には C と絶縁したいという思いが少な : 時代も継続していくことだろう。しかし , り UNIX の地位に揺るぎがないかぎり , C の : メインインプリメンテーション環境 , つま しかし , 別の意味て、間題になるかもしれ三いかもしれない。実際問題としては , その : るときに こんなことを考えるのはおかし : れて , 今まさに絶項期を迎えようとしてい : くのだろうか ? ANSI による標準化が行わ ところて、 , C 言語の全盛時代はいつまて、続 ところが , とがて、きるのて、あろうか ? 方法 ( 目的 ) の違いから引き起こされている三つた場合 , 「標準」や「ポータビリティ」とい・記述する最後のプログラムになるかもしれ この実行結果が異なったものになってしま 両者て、このソースをコンパイルし ( 完全適 : からず存在している。 これは , 何も MS-C と QuickC の間に限っ : 準に完全適合した処理系がふたっ , そして , : こに , ANSI 標 ないとは思う。たとえば , としては , この落し穴に落ちるユーザはあ 54 CMAGAZINE 1990 10 同じマイクロソフト社のふたつの製品が異三 しかし , 一般のユーザから見た場合に きないものて、はない ものて、あり , その動作を推測すると納得て、三 QuickC における相違も , 両者のコード生成 : 個々の処理系の責任て、はない。 MS -C と三するだろう ) 実行したとしよう。 るのだが , すべては , ANSI 規格のあいまい 理系のほとんどて、発生している間題て、はあ : があるものとする。 ものだけを取り上げておいた ) 。 するのだが , 比較的単純に結果が見られる・ ある ( 実際には , もっと多くの間題点が存在三まりいないだろう。 のケースにおいて互換性の取れない場合が : else if(A = else if(A = FIoat else if(A = 本文中て、取り上げたように , MS-C Ver. : なっているのはどうだろうか ? かといっ 5.1 と QuickC Ver. 2.0 の間には , いくっか : てあまり深く追及する気もない。現実問題 たことて、はなく , ANSI 規格準拠をうたう処三標準の構文 / 規約にそって記述されたソース・ な部分に起因している間題て、あり , けして三合なのだから当然コンパイルは無事に完了三 った言葉の意味はどうなってしまうのだろ : ない。その可能性は十分にある。て、は , そ うか ? また , そのような状況て、ほかの組 : のとき , 何を C の代わりにするだろうか ? : 織 , たとえば ISO などに受け入れてもらうこ : C 十十か ObjectiveC, またはそのほかの OOP else (long double)A ; (long double)B ; Double ー B = DoubIe) (double)A : (double)B ; = FIoat) (fIoat)A ; (fIoat)B ; UnsignedLong ー lJnsignedLong) (unsigned long)A ; (unsigned long)B ; else if(A = else if(A = ANSI 規格て、は , 構造体または共用体のメ 関数型メンヾ 構造体 / 共用体における if(A = = SignedLong ー = SignedLong) (signed long)A : (signed long)B ; UnsignedInt ー UnsignedInt) (unsigned int)A ; (unsigned int)B : Signedlnt ー = Signedlnt) (signed int)A ; (signed int)B ; ンバとして関数型 , つまり関数へのポイン タを定義することが許されています。これ は , K & R や 4.2BSD のポータブル C コンパイ ラにおいて禁止されていたものて、す。 式の評価と副作用 C の式が評価されると , その値の生成とと もに副作用 (side effect ) が生み出されます。 この副作用が発生するケースのもっとも一 般的な例は以下のようなものて、しよう。 int x, y, z ; z = x 十十十 y 十十 : この例て、は , b と c を足した値がその評価 結果として a に代入され , 副作用として b お

6. 月刊 C MAGAZINE 1990年10月号

また , 配列のサイズを指定することによ り , 次のような 2 タイプの初期化を行うこと もて、きます。 char cc [ 4 ] ー "ABC" char cc [ 3 ] ー "ABC 上記のふたつの例て、は , 初期化リストの サイズが同一て、あるにもかかわらず , 配列 のサイズ指定が異なっていますが , どちら の場合にも正常にコンパイルが行われます。 配列サイズとして 4 を指定したものは , 配列 サイズを省略した場合と同じ結果となりま すが , 配列サイズ 3 を指定したものは , 以下 のような宣言と等しくなります。 浮動小数接尾子 文字 文字ェスケーフ。 8 進工スケーフ。 1 6 進工スクーフ。 文字列 文字 文字工スケープ 8 進整数 8 進工スケープ char cc [ 3 ] つまり , 文字定数の末尾に存在するはず の \ O 〃は無視されるわけて、す。 型変換 1 6 進整数 1 6 進工スケープ 文字 文字ェスケーフ。 8 進工スケーフ。 1 6 進工スケーフ。 文字定数 式の評価が行われる際の比較的多くの場 合において , char 型から int 型への暗黙的な 拡張変換が行われます。この変換規則を C 言 語のプログラム風にまとめると以下のよう になります。 代入演算子 算術演算子 演算子 代入演算子 if(C = SignedChar) (signed int)C; else if(sizeof(C)== sizeof(unsigned int) (unsigned int)C ; else くく 52 CMAGAZINE 19 10

7. 月刊 C MAGAZINE 1990年10月号

uco ー 0 「 . C List 5 List 5 ワ 3 っ -4 ・ ^ 0 ー 8 0 CO っ 0 っっ 0 っ 0 っっっ -4 ・ 5 : PSKY ;break; case 6 : PYE しし OW ;break; case 7 : PWHITE ;break; case h ” upescape. 1 : #include 2 : 3 : ucolor(sx) 4 : Char SX 6 : unsigned char attr (unsigned char)sx 7 : attr 8 : 9 : if((attr & 0X02 ) ) { PB い NK; if((attr & 0X08 ) ) { PUNDER い NE; if( (attr & 0X04 ) ) { switch( (attr > > 5 ) 17 : 1 : PRB し UE ;break; case 2 : PRRED ;break; case 3 : PRPURP し E ;break,• case 20 : 4 : PRGREEN ;break; case 5 : PRSKY ;break,• case 22 : 6 : PRYEL し OW ;break; case 23 : 7 : PRWHITE ;break; case 24 : 25 : 26 : 28 : 29 : 30 : return( の : up 「 intv. C List 6 1 : # i nc lud e く StdiO. h> 2 : #include upescape. ド 3 : 4 : uprintv(str,attr, ura) 5 : unsigned char str ロ : 6 : char attr ; 7 : int x,y,ura; ucolor (attr) : 9 : P し 0CATE(x,y) : printf("%s", str) : PNONSET; return( の : else{ switch( (attr > > 5 ) case 1 : PB し UE ;break; case 2 : PRED : break : case 3 : PPURPLE •,break; case 4 : PGREEN : break : uscandir. C uselbarC 、関数 イ整理番号ー CM900904 ) 誉を . 、 第を、ト 1 ボックスカソルによる ~ メニュ選択 [ 書式 ] #include く stdio . h 〉 #include く string. h> #include "fkey. h" #include menurd . h ” #include "upldwn. h' #include ” COIO 「 . h ” List 7 1 : #define EXTERN extern 2 : #include く stdio. h> 3 : #include く string. h> 4 : #include く curses. h> 5 : #include "fkey. h" 6 : #include ” menurd. h ” 7 : #include "upldwn. h ” 8 : #include ” c 引 or. h ” 9 : 10 : uselbar(mn,color, rcolor, ー inenum, initl, ura) 1 1 : struct Gmnstr mn ロ : 12 : Char color,rcolor; 13 : i nt linenum, initl,ura; 14 : { 15 : i nt 16 : i nt *pluskey ニ 0 17 : int 1 8 : int selmod 19 : int zen : 20 : i nt mncnt int 22 : i nt dt 1 23 : 24 : Y 25 : for ( i 26 : linenum : 叩 rintv(mn[i]. moji,colorICNONSEC,mn[i]. x,mnCi]. y,ura); 28 : 29 : 30 : 31 : 32 : 33 : 34 : 35 : 36 : 38 : 39 : selbar(mn, CO ー 0 「 , 「 CO ー 0 「 , linenum, initl, ura) ロ ; st 「 uct Gmnstr mn Char CO ー 0 「 , 「 CO ー 0 「・ int linenum, initl, u ra , [ 引数 ] mn ロは , メニュー画面の表示内容のデ ータを収納する構造体てある。 colo 「は通常の表示色てあり , 「 colo 「はリ バース表示する場合の表示色てある。色の 指定方法は , 以下のとおりて、ある。 青 ( 1 * 0X20 十 1 ) , 赤 ( 2 * 0X20 十 1 ) , 108 CMAGAZINE 19 10 linenum : i n i tl uprintv(mn[y]. moji, rc010rlCREVERSElCNONSEC, mn[y]. x, mn[y]. y, ura) : do { zen uscand ir(pluskey) switch(ii){ case CUP: break : case SPACEB ・

8. 月刊 C MAGAZINE 1990年10月号

のことて、す ) 。使用する color cell を , 見つ かった visual 内に作るためには , visual を使 って colormap を作る必要があります。 SetUpC010rmap( ) 関数は , 新たな visual を使って colormap を作り , 次いて、 black 〃 と、、 white 〃用の値を見つけます。この色名 がどのようにマップされるかはわかりませ んが , ともかく本物の黒と白らしい色を期 待するのて、す。 SetUpC010rmap( ) 関数は , display のポイ ンタ , screen 番号 , および visual を引数に取 り , black と white の色のある , 新たな C010r map を返します。 R00tWindow( ) 関数は , screen のルートウインドウ ( ないしべースウ インドウ ) を返すマクロて、す。これは最高レ ベルのウインドウて、あり , その screen のバッ クグラウンドてあると見なされます。ウィ ンドウのパラメータが , ウインドウとして の同じ screen とともに , colormap に結びつ いており , それが screen のデフォルトのウィ ンドウとなります (List 4 ) 。 A Ⅱ ocNone て、はなく , 定数 A Ⅱ OCA Ⅱを渡す と , colormap 中のすべての color cells がア ロケートされます。て、きるだけ少ない C010r cells をアロケートすることによって , この colormap を使った場合のヾテクニカラー効 果 ( 色の不自然さ ) 〃を最小限にしようとし ています。多くのワークステーションて、 , アクテイプなハードウェアの colormap は一 度にひとつだけなのて、 , X window manager がこの colormap に ( および , この colormap から ) 切り換えるとき , これ以外の screen が テクニカラーになることもありえます。 colormap を作ったら , XAllocNamed colo 「 ( ) 関数を使って , 特定の名前とマッチ する C010r value をもった , color cell をアロ ケートて、きますにれはリードオンリの C010r cell なのて , 後からの変更は困難てす ) 。 "white" という名前に関しては , システム のカラーデータベースが参照されます。 構造体 XC010r を ,List 5 に示します opixel フィールドは , colormap 内の位置てす。 red, green および blue の値は , 色を数値的 10 : } 18 : } 16 : 14 : 12 : 9 : 8 : 7 : 4 : 3 : List 7 9 : 7 : 6 : 5 : 4 : 3 : 2 : List 6 status = XAllocNamedCoIor( display, colormap, unsigned long white; XColor hardwarecolor, exactcolor; int status; &exactcolor ) : &hardwarecolor, i f ( sta tus ! = 0 ) { / * 成功 * / white = hardwarecolor. pixel; unsigned int number_planes; unsigned long *plane_masks; 2 : XCoIor the-color; / * われわれの色 * / int status; "white ” 5 : / * プレーンは実際は , DirectC 引 or の分解 c 引 ormap システム用なので , 6 : / * 今回は不要である . * / plane masks = NUL し : number_p lanes ニ XAllocCOIorCells( display, status colormap, FaIse, / * ce Ⅱがただ 1 つなので , 連続的でなくてよい * / plane-masks, number_planes, /*pixel v ue が返される * / &the-color. pixel, /*color ce Ⅱの個数 * / i f ( status ! = 0 ) { / * 成功 * / に記述するものて、す ( List 6 ) 。 次は , この colormap に , リード / ライト可 の C01 cell をアロケートすることが必要て、 す (List 7 ) 。すて、に color cell があるのて、 , それが保持している色を変えることがてき ます。 最後に , 何か適当な RGB の C010r value を セットアップします。 256 色のシステムの多 くが , 16 ビットの RGB 値の上位バイトを使 っているだけなのて、 , 私たちはシフトアッ プをします。読者はぜひ , RGB の値をいろ いろと変えて , 実験してみてください / * 何か ' ' でたらめな " RGB color values をセットアップする * / ( 1 く < 8 ) ; the COIO 「 . red ( 104 く < 8 ) : the COIO 「 . green ( 200 くく 8 ) : the color. blue X は , ビットマップフォントを使ってテキ ストを描画します。フォントを使う前には , それをロードする必要があります。ここて は , XLoadQueryFont( ) 関数 ( 数多いフォン トロード関数のひとつ ) を使って , "fixed" という名前のフォントをロードします。 、 \fixed" というフォントは , ほとんどのシ ステムて、使えるはずてす。それが使えない ときは , xlsfonts というプログラムを使っ て , 利用てきるフォントのリストを入手し , その中から気に入った名前を選びます。 font=XLoadQueryFont( display, fixed" ) : / * トラブル処理 * / ウインドウを 作る ウインドウの作成は , おそらく , X におけ るもっとも困難なタスクてす。ⅵ sual , depth ( その visual がサポートしているカラープレ if( font= = (XFontStruct * ) NULL ) 刈 ib で色を制御する方法 31

9. 月刊 C MAGAZINE 1990年10月号

0 List 1 List 1 184 : } 185 : int setup( unsigned *handle, unsigned *n ) 186 : 187 : { i nt f i nd : 188 : 189 : if ( emm_init() 190 : ex i t ( 1 ) ; 191 : 192 : / * マッヒ。ング可能な物理アドレス配列 paa の取得 * / 193 : get-paa( Pa, n ) : 194 : 195 : if ( search_handle( name, handle ) 196 : 197 : f i nd = NG : 198 : 199 : 200 : 201 : 202 : 203 : } 204 : emm-init( void ) 205 : i nt 206 : / * get interrupt vector 法による EMM の有無チェック * / 207 : i f ( emm ( ) 208 : pr intf ( " 拡張メモリマネージャが組み込まれていません。 Yn" ) : 209 : return( NG ) ; 210 : 211 : 212 : 213 : 214 : 215 : 216 : 217 : 218 : 219 : 220 : 221 : 222 : 223 : 224 : 225 : 226 : } 227 : / * ページのアロケート 228 : int get-pages( uns igned pages, unsigned *handle ) 229 : 230 : 231 : uns igned all-pages, free-pages; 232 : i f ( get_pgcnt( &all-pages, &free_pages ) 233 : pr i nt f ( " 未アロケートページが取得できません . Yn" ) : 234 : return( NG ) ; 235 : 236 : i f ( free_pages く pages ) { 237 : pr i ntf ( " 未アロケートページ数が足りません . Yn" ) : 238 : return( NG ) : 239 : 240 : 241 : 242 : 243 : 244 : 245 : 246 : 247 : } 248 : vo i d co 1 or ( i nt c ) 249 : 250 : 251 : 252 : 253 : 254 : 255 : } printf( " く date>%sYn", buf ) : strncpy ( buf, ems_areal- 〉 time, 10 ) : printf( " く time>%sYn", buf ) : strncpy ( buf, ems_areal->memo, 60 ) : printf( buf ) ; ”く memo>%sYn ” break; case 3 : / * スケジュール削除 * / strncpy ( ems_areal->date, strncpy ( ems_areal->time, strncpy ( ems_areal—>memo, pr i ntf ( " 削除しました . Yn" ) : break; case 4 : / * メモ登録 * / printf( ”く t i 凵 e > gets( buf ) : 20 ) : strncpy ( ems_area2->title, buf, printf( ”く memo>' gets( buf ) : 60 ) : strncpy ( ems_area2->memo, buf, break,• case 5 : / * メモ参照 * / 20 ) : strncpy ( buf, ems_area2->titIe, printf( " く title>%sYn", buf ) : strncpy ( buf, ems_area2->memo, 60 ) : printf( , buf ) : ”く memo 〉 %SYn ” break; case 6 : / * メモ削除 * / strncpy( ems-area2->title, strncpy ( ems_area2->memo, pr i ntf ( " 削除しました . Yn" ) : break; 1 13 : 1 14 : 115 : 1 16 : 1 17 : 1 18 : 1 19 : 120 : 121 : 122 : 123 : 124 : 125 : 126 : 127 : 128 : 129 : 130 : 131 : 132 : 133 : 134 : 135 : 136 : 137 : 138 : 139 : 140 : 141 : 142 : 143 : 144 : 145 : 146 : 147 : 148 : 149 : int menu( void ) 150 : 151 : i nt i , c 1 , c2 ; 152 : 153 : col or ( ー 3 ) : 154 : pr i ntf ( " メニュー Yn" ) : 155 : co I or ( 3 ) : 156 : for ( i 157 : printf( "%sYn", mnlCi] ) : 158 : 159 : co 1 or ( 7 ) : 160 : for ( ・ printf( 162 : ” Enter cl = getche ( ) : 163 : putchar( 'Yn' 164 : if ( strchr( " 123 " , 165 : 166 : putchar( ・ Yn' ) : 167 : を 3 ' ) return( 0 i f ( c 1 168 : co I or ( ー 3 ) : 169 : pr i ntf ( " サプメニュー Yn" ) : 170 : co 1 or ( 3 ) : 171 : 0 : i く 3 : i + + ) { for ( i 172 : printf( "%sYn", mn2[i] ) : 173 : 174 : co 1 or ( 7 ) ; 175 : for ( ・ 176 : printf( "Enter ・ 177 : c2 ニ getche ( ) : 17 8 : putchar( 'Yn ・ ) : 179 : i f ( strchr ( " 123 " , c2 ) 0 ) 1 8 0 : 181 : putchar( 'Yn ・ ) : 182 : return( ( cl 183 : 0 0 0 else { f i nd = OK : return( find ) : " \ 0 " , 20 ) : / * バージョンの取得 i f ( get_version( Version ) pr i nt f ( " E M M が異常です . Yn " ) : return( NG ) : / * ハンドルページのアンマップ * / mapping( emm handle, Pa [ 0 ] . pnum, 0xffff ) : / * E M S ステータスの取得 i f ( get-status ( ) pr i nt f ( " E M M が異常です . \ n " ) : return( NG ) : ニ NC ) { return( OK ) : cl ) 0 ) break; i f ( page-alloc( pages, handle ) pr intf ( " ページアロケートができません . Yn" ) : return( NG ) ; return( OK ) : static char colorbar[] ” 736251404152637 ” : if ( c 〉 7 Ⅱ c く -7 ) printf( "YxIBC%c%cm" break; colorbar[c + 7] ) : ( c2 ワンポイントプログラミング講座 125

10. 月刊 C MAGAZINE 1990年10月号

List 1 1 バイトは ASCII 文字コードそのまま , そし て 2 バイト目は ASCII コード 0X80 という値に なるのだ。 いい換えると , OASYS のシステムは , ういう妙な形式の 2 バイトを見つけると , れは漢字コードなどてはなくて , ふたつの ASCII コードが並んだものて、ある , という判 断をしているのだ。マクロ ASC( ) も , これ と同じ判断をするためのものさ」 何を第誓う″のか , 処女セクタ 23~24 行 <unsigned をわざわざ typedef しているのは , いちいち unsigned とタイプ するのがわずらわしいからだろ ? 「図星 / unsigned cha 「なんて , 13 字もタ イプするからねー さて , グローバル変数だけど , OASYS の ディスク上のデータを読み込むためのバッ ファ (Readbuf) と , MS ー DOS への変換後の データをため込むためのバッファ (Convbuf) を用意している。 5120 というサイズの意味 は , 後て、わかるよ。 Count は , 変換実動ルーチンが数えたカウ ントを , main ( ) が知る必要があるため , グ ローノヾルにしている。 41 , 42 行目の Margin iki と Kei iki は , 左右 マージン ( 1 行を 40 字未満て作った行の左右 の空き ) や罫線を , 変換においてスキップす るか否かのフラグさ。 配列 Tokushu ロは , 変換可能な特殊文字 のコードのペアを並べたものだ。これが現 状て、 NofToku 個 , つまり 97 個あるんだ。た だし , 罫線文字の一部は , 完全に対応して いないのて , 代用コードを使っている。 bsea 「 ch( ) が , この配列を探索することになるの て , 正しくソートされていなければならな ソートとは , めんどうだね。 「そんなことはないよ。この配列だけのファ イルを作っておいて , MS-DOS の SORT コ マンドを使えば , 簡単さ。 次の *er 「 msg ロは , ディスク BIOS 用の 工ラーメッセージの配列だね。これは , 参 *errmsg ロニ { / * DISK BIOS Error Messages * / 144 : Char "Normal End (Ready if SENSE command) " 145 : "Contr01 Mark()r ite Protect if SENSE command) " 146 : "DM Boundary" 147 : 148 : ” End of CY linder ” 149 : ” Equ ipment Check ” 150 : ” 0ver Run ” 151 : ” Not Ready ” 152 : ” Not Writable ” ” Error(80h)" 153 : ” Time 0ut ” 154 : 155 : "ID CRC error ” , 156 : ” DATA CRC error ” , 157 : ” No Data ” 158 : ” Bad Cylinder ” 159 : "Missing ID Åddress Mark" 160 : "Missing DATA Address Mark" 161 ・ 162 : 163 : / * 164 : 98 対応引 S 文字なら 1 を返す 165 : * / 166 : int jis98(byte first. byte second) 168 : if(f irst==0x22 & & second>0x2f) 169 : return ( の : 170 : e ー se return ( 1 ) : 171 : 172 : } 173 : 174 : / * 175 : J I S 漢字コードをシフト引 S コードに変換 176 : * / 177 ・ ・ word jistosjis(byte jl, byte j2) 178 : { 179 : word sjis, tmp; 180 : byte sl, s2; 181 : s2 ニ ( jl % 2 ) ? j2 + 0xlf : j2 + 0x7d : 182 : 183 : if(s2>=0x7f) 184 : 十十 s2 : if ( ( sl = ( ( j ト 0X21 ) ” 1) + 0x81) > 0x9f) 185 : 186 : sl + ニ 0X40 : 187 : sjis=sz; 188 : tmp=sl: 189 : tmp く←8: return (sjisl tmp) : 190 : 191 : } 192 : 193 : / * 194 : OASYS のセクタの内容を MS - DOS データに変換 195 : * / void convert(i nt start) 196 : 198 : register word data; 199 : register byte *cvp; 200 : byte *Oap; 201 : int sec, l, J, end; 202 : byte c0, cl, c2; 203 : 204 : Count=0; 205 : oap=Readbuf: 206 : cvp=Convbuf; for(sec=start; sec く 6: 十十 sec) { /*sector 1 to 5 * / 207 : if ( * oap = 0X40 & & * (oap + 1) = 0X40 & & 208 : * ( oap + 2 ) ニ = 0X40 & & * ( oap + 3 ) = 0X40 ) { 209 : sector*/ oap 十ニ 1024 : /*skip a 210 : /*unused sector=a Ⅱ・ 0X40 ・ * / continue; 211 : 212 : end=0: 213 : for(i=0; i<12: + + i ) { 214 : for(j=0; j く 40 : + + j ) { 215 : if(end) { 216 : oap 十ニ 2 : 217 : continue; 218 : 219 : cO = * oap 十十 : 220 : 221 : Cl : * oap 十十 : c2=c0 & 0x7f; 222 : if(ASC(c2. cl)){ 223 : cl&=0x7f; 224 : if(isprint(cl)){ 225 : *cvp 十十ニC2: 226 : *cvp 十十 =cl : 227 : Count + :2: 228 : 229 : )else if(c0==0x2f) { 230 : if(c1==0x22) { 231 : 0 /*line 1 to 12 * / /*2byte char 1 tO 40 * / /*after EOF*/ /*clear bit 7 0f lst byte*/ /*ASCII char*/ /*OASYS control 0x2fnn*/ Char 113 C 言語フォーラム