高度な検索
Developer Connection
Member Login ログイン | ご入会 ADC連絡先

Technote 1152

JIS Keyboard Support in Mac OS 8


CONTENTS

JIS キーボード

Mac OS 8 以前の状況

Mac OS 8 での改良

ことえり 2.0

要約

ダウンロード

のテクニカルノートは、Mac OS 8 で導入された JIS キーボードをサポートするための新しい仕組みについて記述したものです。このテクニカルノートはキーボード配列に依存するようなインプットメソッドやアプリケーションを開発するデベロッパを対象にしています。

JIS キーボード

現在、日本の市場には Macintosh 用のキーボードとして、JIS 配列のキーボード(以下 JIS キーボードと記述)と US 配列のキーボード(以下 US キーボードと記述)の2種類のキーボードが存在します。JIS キーボードは下の iMac キーボードのように、日本語入力用キーの追加など、いくつかの点で US キーボードと異なります。



図1: 日本で販売されている iMac のキーボード配列


Mac OS 8 以前の状況

US と JIS キーボードの両方をサポートするために、Mac OS 7.6.1 までの OS はシステムファイルに以下の6つのキーボードレイアウトリソースが実装されていました。

名称 スクリプト 入力方法 キーボード配列
カナ日本語かな入力US
カナ - JIS日本語かな入力JIS
ローマ字日本語ローマ字入力US
ローマ字 - JIS日本語ローマ字入力JIS
U.S.ローマンN/AUS
Roman - JISローマンN/AJIS

表1: Mac OS 7.x に実装されているキーボードレイアウトリソース
(リソースタイプ 'KCHR'

ユーザはインストールされている各々のスクリプトに対して、キーボードコントロールパネルで正しいキーボードレイアウトリソースを選択する必要がありました。キーボードコントロールパネルには現在選択されているスクリプトに対するキーボードレイアウトリソースのみが表示されるため、例えば通常の日本語システムの場合でも、日本語と Roman の両方を設定しなければなりませんでした。

例えば、JIS キーボードを使用する場合、ユーザはまずキーボードコントロールパネルで“Roman - JIS”を選択します。



図2: キーボードコントロールパネルで“Roman - JIS”を選択

次に、スクリプトメニューを日本語に切り替え、入力方法の好みに応じて“かな - JIS”または“ローマ字 - JIS”を選択します。




図3: スクリプトを日本語に切り替える



図4: キーボードコントロールパネルで“かな - JIS”を選択

註:
キーボードレイアウトリソースの設定値は再起動後も保たれますが、システムスクリプトは起動時にリセットされます。


仮に誤って実際に接続されているキーボードと異なるキーボードレイアウトリソースを選択した場合は、英字が正しく入力できなくなる問題が起きます。例えば、JIS キーボードが接続されているにもかかわらず US のキーボードレイアウトリソースを選択した場合、一部のキーは keyDown イベントを発生させなくなります。これは JIS キーボードが US キーボードに存在しないキーを含んでいるためで、US のキーボードレイアウトリソースはこのようなキーを nil のキャラクタコードにマップしています。nil のキャラクタコードは keyDown イベントを発生させません。さらに、一部のキーは全く異なるキャラクタにマップされてしまいます。

Mac OS 8 以前のもう一つの問題は、接続されているキーボードが JIS かどうかを特定する確実な方法がなかったことです。このため、インプットメソッドは JIS キーボードだとわかっているキーボード ID を内部で持つようになりました。内部で持っているキーボード ID を KbdType ローメモリ変数と比較すれば、接続されているキーボードが JIS かどうかがすぐ確認できますが、このような手法を取っていたインプットメソッドは、アップルが新たな JIS キーボードを出荷する度にソフトウェアをアップデートしなければなりませんでした。

最後に、Mac OS 8 以前のメカニズムでは、キーボードコントロールパネルで“かな入力”か“ローマ字入力”と言う設定がありましたが、インプットメソッド側でも同じような設定があったため、ユーザにとってわかりにくいと言う問題がありました。


上に戻る

Mac OS 8 での改良

アップルでは、Mac OS 8 において、これらの問題を解決するために以下の改良を行いました。

  • 新しいキーリマップリソース

    接続されているキーボードの種別に応じて、キーボードコントロールパネルの設定を必要とする代わりに、Mac OS 8 では JIS キーボードをサポートするためのキーリマップリソース(リソースタイプ 'itlk')が追加されました。キーボード種別の違いをキーリマップリソースで吸収するため、JIS キーボード用のキーボードレイアウトリソースはすべて必要なくなり、Mac OS 8 からは削除されています。

    名称 スクリプト 入力方法 キーボード配列
    カナ日本語かな入力特定しない
    ローマ字日本語ローマ字入力特定しない
    U.S.ローマンN/A特定しない

    表2: Mac OS 8 に実装されているキーボードレイアウトリソース
    (リソースタイプ 'KCHR'

    キーボードレイアウトリソースとキーボード種別の関係を切り離すことで、上記の3リソースのみで JIS と US キーボードがサポートできるようになりました。

  • KBGetLayoutType

    Mac OS 8 では、インプットメソッドやアプリケーションがキーボード種別を知る必要のある場合、KBGetLayoutType を利用して判断することができます。KBGetLayoutType を利用することによって、JIS キーボードの ID を内部で維持する必要がなくなり、アップルが新しいキーボードを導入した場合でも正しく動作します。なお、KBGetLayoutType を使用するには、KeyboardsLib ライブラリが必要です。

  • キーボードコントロールパネルの改良

    アップルは Mac OS 8.0 で新しいキーボードコントロールパネルを導入しました。ユーザインタフェースの統合と改良に加えて、新しいコントロールパネルは2バイトスクリプトのキーボードレイアウトリソースを全く表示しません。キーボード種別の選択はキーリマップリソースによって必要なくなりました。また、入力方法の設定もインプットメソッド側で行われるため、コントロールパネルでは機能が必要なくなりました。

以下に、上記の変更の各々について詳しく説明いたします。

新しいキーリマップリソース

キーボードのキーが押された時、そのキーボードと同じリソース ID を持つキーマップリソース(リソースタイプ 'KMAP')を経由して、仮想キーコードが発生します。Event Manager はこの仮想キーコードを使いやすいキャラクタコードに変換し、その後 keyDown イベントとしてアプリケーションに渡します。キーリマップリソース(リソースタイプ 'itlk')は KeyTranslate 関数内で仮想キーコードを別の新しい仮想キーコードにマップします。詳しくは Inside Macintosh: Text, Appendix C, C-16 をご覧下さい。




図5: キーリマップリソースによる仮想キーコードのリマップの仕組み

キーリマップリソースが存在しない場合はどうなるでしょうか?

例えば、JIS の Apple Keyboard II(キーボード ID 22)の“@”キーが押された時、仮想キーコード 0x21 が発生します。その時に選択されているキーボードレイアウトリソースが“Roman - JIS”の場合、KeyTranslate0x210x40 にマップします。これは“@”記号の正しいキャラクタコードです。




図6: JIS キーボードで“Roman - JIS”が選択されている時に“@”キーを押す

この時、誤って“U.S.”キーボードレイアウトリソースが選択されていると、KeyTranslate は“U.S.”の 'KCHR' を経由して、キャラクタコード 0x5B(“[”)を発生させてしまい、キートップにプリントされている“@”と異なるキャラクタを生成してしまうことになります。




図7: JIS キーボードで“U.S.”が選択されている時に“@”キーを押す

US キーボードで“U.S.”キーボードレイアウトリソースを経由して、キャラクタコード 0x40(“@”)を発生させるには、修飾キーとして shift キーが押されており、仮想キーコードとして 0x13 が渡される必要があります。




図8: US キーボードで“U.S.”が選択されている時に“@”を生成する

JIS キーボードで“Roman - JIS”ではなく“U.S.”キーボードレイアウトリソースを経由して、キャラクタコード 0x40(“@”)を発生させるには、修飾キーとして shift キーが押されたのと同じ状況をキーリマップリソースが作りだし、仮想キーコードとして 0x13 が渡される必要があります。




図9: JIS キーボードで“U.S.”が選択されている時に“@”を生成する

このように、適切なキーリマップリソースを作成することにより、“U.S.”、“ローマ字”、“カナ”のキーボードレイアウトリソースだけで JIS キーボードと US キーボードの2種類のキーボードをサポートすることができるようになります。

Mac OS 8.5.1 でサポートされている JIS キーボード

Mac OS 8.5.1 現在、以下のキーボード ID が JIS キーボードとして認識されます。今後新たな JIS キーボードが登場すれば、そのキーボード ID も Mac OS に追加されます。

キーボード ID JIS キーボード
18Apple Adjustable Keyboard
21PowerBook 500 シリーズ
PowerBook 1400 シリーズ
PowerBook 3400 シリーズ
PowerBook G3(オリジナル)
22Apple Keyboard II
23Reserved
26Reserved
30PowerBook 2400 シリーズ
194Reserved
197PowerBook G3 シリーズ
200iMac
Power Macintosh G3(Blue & White)
201PowerBook G3(1999)

キーリマップリソースによって変更されるキー

Mac OS 8 のキーリマップリソースによって変更される個々のキーは下記の通りです。(下記のキーの数字はキーコードを表しています。)

各キーリマップリソース('itlk')によって、
キーボードレイアウトリソース('KCHR')の処理の前にリマップされるキー
カナ ローマ字 U.S.
0x18
0x5D
0x21
0x1E
0x27
0x2A
0x5E
0x5F
0x66
0x68
0x13
0x16
0x1A
0x1C
0x19
0x1D
0x1B
0x18
0x5D
0x21
0x1E
0x29
0x27
0x2A
0x5E
0x5F
0x66
0x68
0x13
0x16
0x1A
0x1C
0x19
0x1D
0x1B
0x18
0x5D
0x21
0x1E
0x29
0x27
0x2A
0x5E
0x5F
0x66
0x68

KBGetLayoutType

コンピュータに接続されているキーボードの種別(JIS また非 JIS)を知る必要のあるインプットメソッドやアプリケーションはキーボードライブラリの KBGetLayoutType をご使用下さい。

キーボードライブラリは Mac OS 8.x 日本語版のみに含まれていることや、Mac OS 8.5 のバグのため、API を利用する前の存在の確認は不可欠です。確認方法や、存在しない場合の対処方法については以下のサンプルコードをご覧下さい。

キーボードライブラリはダウンロードの上、リンクしてご使用下さい。.

注意:
Mac OS 8.5 日本語版に含まれている KeyboardsLib 1.1 はバグにより KBGetLayoutType がクラッシュすることがあります。(Mac OS 8.5 アップデートや Mac OS 8.6 では解決されています。)

不幸中の幸いにも、キーボードライブラリは Mac OS 8.5 のタイミングで PowerPC のみの共有ライブラリになったため、非公開だった 'kbds' Gestalt セレクタが外されました。KeyboardsLib 1.1.1 以後では 'kbds' Gestalt セレクタが復活しています。'kbds' セレクタはここで公開するとともに、Mac OS のすべてのバージョンで、キーボードライブラリの有無を確認する方法として推奨します。

キーボードの種別を確認する場合、アップルの推奨する方法は、以下のサンプルコードのように、わかっているキーボードデバイスを内部で持ち、わからないデバイスについて KBGetLayoutType を利用することです。


/*  KBLayout.h  */

#ifndef __MACTYPES__
#include 
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if ! defined (__KEYBOARDS__)

enum {
    gestaltKeyboardsLib = FOUR_CHAR_CODE('kbds')     /* キーボードライブラリ */
};

enum
{
    kKeyboardJIS     = 'JIS ',
    kKeyboardANSI    = 'ANSI',
    kKeyboardISO     = 'ISO ',
    kKeyboardUnknown = '????'
};

enum
{
    _KeyboardDispatch = 0xAA7A
};

#pragma import on
extern pascal OSType KBGetLayoutType (short deviceID)
 THREEWORDINLINE(0x303C, 0x0007, _KeyboardDispatch);
#pragma import off

#endif

OSType GetKeyboardLayoutType (short deviceID);

#ifdef __cplusplus
}
#endif

/*  KBLayout.c  */

#include 
#include 
#include 
#include "KBLayout.h"

Boolean IsKBGetLayoutTypeAvailable (void);

/*  キーボード配列を返します  */

OSType GetKeyboardLayoutType (short deviceID)
{
    OSType keyboardLayoutType;

    switch (deviceID) {
        case 0x01:
        case 0x02:
        case 0x03:
        case 0x06:
        case 0x08:
        case 0x0C:
        case 0x10:
        case 0x18:
        case 0x1B:
        case 0x1C:
        case 0xC0:
        case 0xC3:
        case 0xC6:
            keyboardLayoutType = kKeyboardANSI;
            break;
        case 0x12:
        case 0x15:
        case 0x16:
        case 0x17:
        case 0x1A:
        case 0x1E:
        case 0xC2:
        case 0xC5:
        case 0xC8:
        case 0xC9:
            keyboardLayoutType = kKeyboardJIS;
            break;
        case 0x04:
        case 0x05:
        case 0x07:
        case 0x09:
        case 0x0D:
        case 0x11:
        case 0x14:
        case 0x19:
        case 0x1D:
        case 0xC1:
        case 0xC4:
        case 0xC7:
            keyboardLayoutType = kKeyboardISO;
            break;
        default:
            if (IsKBGetLayoutTypeAvailable ())
                keyboardLayoutType = KBGetLayoutType (deviceID);
            else
                keyboardLayoutType = kKeyboardUnknown;
            break;
    }
    return keyboardLayoutType;
}

/*  KBGetLayoutType が使用可能な場合のみ、true を返します  */

Boolean IsKBGetLayoutTypeAvailable (void)
{
    long response;

    if (Gestalt (gestaltKeyboardsLib, &response) == noErr)
        return true;
    else
        return false;
}

キーボードコントロールパネルの改良

キーボードコントロールパネルの“スクリプト”ポップアップメニューには、日本語を含む任意の2バイトスクリプトは表示されません。キーボードコントロールパネルがいままで提供していた機能は必要なくなったか、インプットメソッド側に委ねられています。



図10: Mac OS 8.5 のキーボードコントロールパネル

インプットメソッドやアプリケーションの互換性の注意点

多くのインプットメソッドは、インプットメソッド自身が内部に各キーボードに対するキーボードレイアウトリソース(リソースタイプ 'KCHR')を持ち、接続されているキーボードに応じてリソースを切り替えて使用し、キャラクタコードを得ています。この方法は Mac OS 8 でも使用できますが、互換性に関して以下の問題が発生する可能性があるので注意が必要です。

  1. キーリマップリソースの導入により下記のキーボードレイアウトリソースは必要なくなり、Mac OS 8 から削除されています。以前 Mac OS に組み込まれていた下記のリソースに依存しているアプリケーションやインプットメソッドは変更が必要となります。

    名称 スクリプト 入力方法 キーボード配列
    かな - JIS日本語かな入力JIS
    ローマ字 - JIS日本語ローマ字入力JIS
    Roman - JISローマンN/AJIS

    表3: Mac OS 8 で削除されたキーボードレイアウトリソース
    (リソースタイプ 'KCHR'


  2. キーリマップリソースの構造上の制限により、以下の4つの場合に限り、JIS キーボードを使って正しいキャラクタコードが発生しません。従って、これらのショートカットを利用しているインプットメソッドやアプリケーションでは問題が発生する場合があります。

    • “¥”と修飾キー

      option + “¥”
      option + shift + “¥”
      option + shift + コマンド + “¥”
      option + shift + caps lock + “¥”
      option + shift + コマンド + caps lock + “¥”
      は“|”記号(0x7C)を生成しません。

    • “@”と修飾キー

      コマンド + “@”
      コマンド + shift + “@”
      コマンド + caps lock + “@”
      コマンド + shift + caps lock + “@”
      option + “@”
      option + コマンド + “@”
      option + コマンド + caps lock + “@”
      control + 任意の修飾キー + “@”
      は“@”記号(0x40)を生成しません。

    • “:”と修飾キー

      コマンド + “:”
      コマンド + Shift + “:”
      コマンド + caps lock + “:”
      コマンド + Shift + caps lock + “:”
      option + shift + “:”
      option + shift + コマンド + “:”
      option + shift + caps lock + “:”
      option + shift + コマンド + caps lock + “:”
      option + “:”
      control + 任意の修飾キー + “:”
      は“:”記号(0x3A)を生成しません。

    • “_” と修飾キー

      コマンド + “_”
      コマンド + caps lock + “_”
      コマンド + shift + “_”
      コマンド + shift + caps lock + “_”
      option + “_”
      option + コマンド + “_”
      option + コマンド + caps lock + “_”
      option + shift + “_”
      option + shift + コマンド + “_”
      option + shift + caps lock + “_”
      option + shift + コマンド + caps lock + “_”
      は“_”記号(0x5F)を生成しません。


上に戻る

ことえり 2.0

Mac OS 8.0 はことえり 2.0 を搭載しています。ことえり 2.0 は上記で説明した仕組みを利用してキーボード配列を見分けています。ここでは、ことえり 2.0 が、どのようにこの仕組みを利用しているのかを説明します。

基本的に、ことえり 2.0 は Text Services Manager から送られてきたキャラクタコードをそのまま使用しています。“かな入力”や“ローマ字入力”といった入力方法に応じたキーボードレイアウトリソースの切り替えはシステムのキーボードレイアウトリソースを切り替えることによっておこなっています。つまり、“かな入力”の場合にはシステムの 'KCHR' をリソース ID = 16384 の“カナ”'KCHR' に切り替え、“ローマ字入力”の場合にはシステムの 'KCHR' をリソース ID = 16385 の“ローマ字”'KCHR' に切り替えます。同様に、“かな入力”が設定されている場合に、英数モードに切り替える場合も、システムの 'KCHR' をリソース ID = 16385 の“ローマ字”'KCHR' に切り替えます。システムの 'KCHR' の切り替えは下記のように行ないます。詳しくは Inside Macintosh: Text, Appendix C, C-22 をご覧下さい。

OSErr SetSystemKCHR (short resourceID)
{
    OSErr error;

    error = SetScriptVariable (smJapanese, smScriptKeys, resourceID);
    if (error == noErr) {		
        error = SetScriptVariable (smJapanese, smScriptIcon, resourceID);			
        if (error == noErr)
            KeyScript (smJapanese);
    }	
    return error;
}

注意:
日本語のインプットメソッドは日本語の時にのみ動作するので、KeyScript の呼び出しは必要ないように見えるかもしれません。しかし、これは SetScriptVariable の結果を正しく反映するために必要です。

警告:
キーリマップリソースが正しく動作するためには、使用する 'KCHR' を上記のように実際にシステムに設定する必要があります。GetResource で取得した 'KCHR' へのポインタを KeyTranslate に渡す方法ではキーリマップリソースが正しく処理されません。

ことえりは caps lock キーを使った入力モードの切り替え機能を提供していますが、この機能を実装するために、caps lock キーが押されている場合は caps lock キーが押されていることを示すビットを修飾から取り除き、GetScriptManagerVariable (smKCHRCache) で得られたポインタを KeyTranslate に渡して、caps lock キーが押されていない状態で発生するキャラクタコードを得ています。


上に戻る

要約

日本市場で使用されるアプリケーションやインプットメソッドは複数のキーボード配列を念頭に入れる必要があります。コンピュータに接続されているキーボードの種別の判断は上記サンプルコードのように KBGetLayoutType をご使用下さい。


参考文献

  • Event Manager
    KeyTranslate をはじめとする、キーイベント処理全般について記述されています。
  • Keyboard and International Resources
    このテクニカルノートに出てくるキーマップ(“'KMAP'”)、キーリマップ(“'itlk'”)、キーボードレイアウト(“'KCHR'”)リソースの解説です。
  • Script Manager
    SetScriptVariableGetScriptVariable など、Script Manager の技術文献です。

上に戻る

ダウンロード

Binhexed KeyboardsLib (2K)


Change History

  • 03/97 - DTS Japan Technote 10009 として発行
  • 07/97 - 更新
  • 10/98 - サンプルコードは Mac OS 8.5 のバグを回避するように修正
  • 02/99 - Mac OS 8.5.1 に関する変更点を記述

上に戻る


更新日: 1999 年 2 月 22 日