キーボード入力とテキスト出力はどのように機能しますか?


85

Aテキストエディタでキーを押すとa、ドキュメントに文字が挿入され、画面に表示されます。エディターアプリケーションがハードウェアと直接通信していないことは知っています(カーネルとその間にあるものがあります)。そのため、コンピューター内で何が起こっているのでしょうか。

回答:


100

いくつかの異なるシナリオがあります。最も一般的なものについて説明します。連続する巨視的なイベントは次のとおりです。

  1. 入力:キーを押すイベントがキーボードハードウェアからアプリケーションに送信されます。
  2. 処理:アプリケーションは、キーAが押されたため、文字を表示する必要があると判断しますa
  3. 出力:アプリケーションはa、画面に表示する順序を指定します。

GUIアプリケーション

UNIXシステムの事実上の標準グラフィカルユーザーインターフェイスは、アプリケーションとディスプレイサーバー間のコアプロトコルの11番目のバージョンで安定したため、しばしばX11と呼ばれるX Window Systemです。Xサーバーと呼ばれるプログラムは、オペレーティングシステムのカーネルとアプリケーションの間にあります。画面にウィンドウを表示したり、フォーカスを持っているウィンドウにキーを押したりするなどのサービスを提供します。

入力

+----------+              +-------------+         +-----+
| keyboard |------------->| motherboard |-------->| CPU |
+----------+              +-------------+         +-----+
             USB, PS/2, …                 PCI, …
             key down/up

まず、キーの押下とリリースに関する情報がキーボードからコンピューターとコンピューター内部に送信されます。詳細はハードウェアの種類によって異なります。情報はチェーンのこの部分全体で同じままであるため、この部分については詳しく説明しません。特定のキーが押されたか、離されました。

         +--------+        +----------+          +-------------+
-------->| kernel |------->| X server |--------->| application |
         +--------+        +----------+          +-------------+
interrupt          scancode             keysym
                   =keycode            +modifiers

ハードウェアイベントが発生すると、CPUは割り込みをトリガーします。これにより、カーネル内の一部のコードが実行されます。このコードは、ハードウェアイベントがキーボードからのキーの押下またはキーの解放であることを検出し、キーを識別するスキャンコードを記録します。

Xサーバーは、たとえばLinux(NNNは数字)上のデバイスファイルを通じて入力イベントを読み取ります/dev/input/eventNNN。イベントが発生するたびに、カーネルはそのデバイスから読み取るデータがあることを通知します。デバイスファイルは、キーアップ/ダウンイベントをスキャンコードで送信します。スキャンコードは、ハードウェアによって送信される値と同一である場合とそうでない場合があります(カーネルはスキャンコードをキーボード依存の値から共通の値に変換し、Linux は知らないスキャンコードを再送信しないでください)。

Xは、キーコードを読み取るスキャンコードを呼び出します。Xサーバーは、キーコードをkeysyms(「キーシンボル」の略)に変換するテーブルを保持しています。キーシンボルのような名前であるのに対し、キーコードは、数字でありAaacuteF1KP_AddControl_L、...キーシンボルは、(修飾キーが押されているかに応じて異なってもよいですShiftCtrl...)。

キーコードからキーシムへのマッピングを構成するには、次の2つのメカニズムがあります。

  • xmodmapは従来のメカニズムです。これは、キーコードをキーシムのリスト(未変更、シフト、…)にマッピングする単純なテーブルです。
  • XKBはより強力ですが、より複雑なメカニズムであり、特に2言語構成など、より多くの修飾子をより適切にサポートします。

アプリケーションはXサーバーに接続し、そのアプリケーションのウィンドウにフォーカスがあるときにキーが押されると通知を受け取ります。この通知は、特定のキーシムが押されたか放されたことと、現在押されている修飾子を示します。xev端末からプログラムを実行すると、keysymsを表示できます。アプリケーションが情報をどのように処理するかは、次第です。一部のアプリケーションには、構成可能なキーバインドがあります。

通常の構成では、A修飾子なしのラベルが付いたキーを押すと、keysym aがアプリケーションに送信されます。アプリケーションがテキストを入力するモードにある場合、これは文字を挿入しますa

キーボードレイアウトとxmodmapの関係は、キーボード入力についてさらに詳しく説明します。Linuxではマウスイベントはどのように機能しますか?下位レベルでのマウス入力の概要を示します。

出力

+-------------+        +----------+          +-----+         +---------+
| application |------->| X server |---····-->| GPU |-------->| monitor |
+-------------+        +----------+          +-----+         +---------+
               text or              varies          VGA, DVI,
               image                                HDMI, …

キャラクターを表示するには2つの方法があります。

さまざまなタイプのXWindowsフォントの目的は何ですか?を参照してくださいX11でのクライアント側およびサーバー側のテキストレンダリングの説明。

Xサーバーとグラフィックスプロセッシングユニット(ビデオカードのプロセッサ)の間で起こることは、ハードウェアに大きく依存しています。単純なシステムでは、Xサーバーがフレームバッファーと呼ばれるメモリ領域に描画し、GPUがそれを表示用に取得します。21世紀のPCやスマートフォンに見られるような高度なシステムにより、GPUはパフォーマンスを向上させるためにいくつかの操作を直接実行できます。最終的に、GPUは画面コンテンツを1秒ごとにピクセル単位でモニターに送信します。

ターミナルで実行されているテキストモードアプリケーション

テキストエディタがターミナルで実行されているテキストモードアプリケーションである場合、上記のセクションの目的のためのアプリケーションはターミナルです。このセクションでは、テキストモードアプリケーションと端末間のインターフェイスについて説明します。最初に、X11で実行されているターミナルエミュレータの場合について説明します「端末」、「シェル」、「tty」、「コンソール」の正確な違いは何ですか?ここで役に立つ背景かもしれません。これを読んだ後、あなたははるかに詳細を読むことができます。各擬似端末(PTY)コンポーネント(ソフトウェア、マスター側、スレーブ側)の責任は何ですか?

入力

      +-------------------+               +-------------+
----->| terminal emulator |-------------->| application |
      +-------------------+               +-------------+
keysym                     character or
                           escape sequence

端末エミュレータは、「ダウンLeftShiftに押されました」などのイベントを受信します。ターミナルエミュレータとテキストモードアプリケーション間のインターフェイスは、バイトを送信するキャラクタデバイスである擬似ターミナル(pty)です。端末エミュレーターは、キー押下イベントを受信すると、これを1つまたは複数のバイトに変換し、アプリケーションがptyデバイスから読み取るようにします。

ASCII範囲の外の印刷可能なキャラクタは、キャラクタとコード化に依存して1つ以上のバイトとして伝えられます。たとえば、Unicode文字セットのUTF-8エンコードでは、ASCII範囲の文字は単一バイトとしてエンコードされ、その範囲外の文字は複数バイトとしてエンコードされます。

ファンクションキーやのような修飾子で印刷可能な文字に対応し、キーを押すCtrlか、をAltとして送信されるエスケープシーケンス。エスケープシーケンスは通常、文字エスケープ(バイト値27 = 0x1B = \033^[またはとして表されることもある\e)と、それに続く1つ以上の印刷可能文字で構成されます。いくつかのキーまたはキーの組み合わせを持っている制御文字(Unicodeを、使用中の今日のほとんどすべてのそれらのある含めて)ASCIIベースのエンコーディングでそれらに対応:Ctrl+は、letter範囲1-26内の文字値を生成し、Escエスケープ文字があります上記見ても同じであるCtrl+ [Tab同じですCtrl+ IReturnCtrl+ Mなどと同じです。

異なる端末は、特定のキーまたはキーの組み合わせに対して異なるエスケープシーケンスを送信します。幸いなことに、その逆は当てはまりません。シーケンスが与えられると、実際には、エンコードするキーの組み合わせは最大で1つです。唯一の例外は、文字127 = 0x7fの=である\0177ことが多いですBackspaceが、時にはDelete

端末では、Ctrl+のV後にキーの組み合わせを入力すると、エスケープシーケンスの最初のバイトがキーの組み合わせからそのまま挿入されます。エスケープシーケンスは通常、最初の文字の後の印刷可能な文字のみで構成されるため、エスケープシーケンス全体が文字通り挿入されます。キーバインディングテーブルを参照してくださいこのコンテキストでのzshの説明。

端末は、いくつかの修飾子の組み合わせに対して同じエスケープシーケンスを送信する場合があります(たとえば、多くの端末 + SpaceShift+の両方にスペース文字を送信しSpaceます。xtermには修飾子の組み合わせを区別するモードがあります、一般的なvteライブラリに基づく端末はそうではありません)。修飾キーやターミナルエミュレーターのバインドをトリガーするキー(コピーまたは貼り付けコマンドなど)など、いくつかのキーはまったく送信されません。

必要に応じて、エスケープシーケンスをシンボリックキー名に変換するのはアプリケーション次第です。

出力

+-------------+               +-------------------+
| application |-------------->| terminal emulator |--->
+-------------+               +-------------------+
               character or
               escape sequence

出力は入力よりも簡単です。アプリケーションがptyデバイスファイルに文字を出力する場合、ターミナルエミュレーターは現在のカーソル位置に文字を表示します。(ターミナルエミュレータはカーソル位置を維持し、カーソルが画面の下部に収まる場合はスクロールします。)アプリケーションは、エスケープシーケンス(主に^[またはで始まる^])を出力して、カーソルの移動などのアクションを実行するように端末に指示することもできます。テキスト属性(色、太字など)を変更するか、画面の一部を消去します。

端末エミュレーターでサポートされているエスケープシーケンスは、termcapまたはterminfoデータベースに記述されています。現在、ほとんどの端末エミュレータはxtermとかなり密接に連携しています。LESS_TERMCAP_ *変数に関するドキュメントを参照してください端末能力情報データベースの長い議論のために、そしてどのように点滅からカーソルを停止する、私は私がにsshを機械のそれらを使用するために私のローカルマシンのターミナルの色を設定することはできますか?いくつかの使用例。

テキストコンソールで実行されているアプリケーション

アプリケーションがテキストコンソール、つまりターミナルエミュレータアプリケーションではなくカーネルによって提供されるターミナルで直接実行されている場合、同じ原則が適用されます。端末とアプリケーション間のインターフェイスは、エスケープシーケンスとしてエンコードされた特別なキーとコマンドを使用して、文字を送信するバイトストリームのままです。

ネットワーク経由でアクセスするリモートアプリケーション

リモートテキストアプリケーション

SSHなどのリモートマシンでプログラムを実行する場合、ネットワーク通信プロトコルはptyレベルでデータを中継します。

+-------------+           +------+           +-----+           +----------+
| application |<--------->| sshd |<--------->| ssh |<--------->| terminal |
+-------------+           +------+           +-----+           +----------+
               byte stream        byte stream       byte stream
               (char/seq)         over TCP/…        (char/seq)

これは、リモート端末データベースがローカル端末のすべての機能を認識しない場合があることを除いて、ほとんど透過的です。

リモートX11アプリケーション

アプリケーションとサーバー間の通信プロトコルは、それ自体がバイトストリームであり、SSHなどのネットワークプロトコルを介して送信できます。

+-------------+            +------+        +-----+            +----------+
| application |<---------->| sshd |<------>| ssh |<---------->| X server |
+-------------+            +------+        +-----+            +----------+
               X11 protocol        X11 over       X11 protocol
                                   TCP/…

これは、アプリケーションとディスプレイ間の直接通信を必要とするムービーデコードや3Dレンダリングなどの一部のアクセラレーション機能が利用できないことを除いて、ほとんど透過的です。


完全には定かではありませんが、答えは一般にかなり詳細であるため、「テキストコンソールで実行中のアプリケーション」という部分がtoのman 5 keymaps翻訳に使用されるような機能を備えていないのではないかと思います。原則として似ているが、それはまだまったく異なるツール/プログラムのセットであり、これはおそらくより多くの洞察に値するでしょう。その横にある答えは+1で、関連する質問が埋め込まれているので素晴らしいです。keycodesscancodes
humanityANDpeace

私が見つかりましたPgUpCtrl+PgUpTTY1(TERM = linuxの)に区別することはできません。keysym->制御シーケンスマッピングを構成できますか?
-stewbasic

@stewbasicはい、キーマップがによってロードされていloadkeysます。linux console keyboard-layoutとタグ付けされた質問を検索します
ジル

@Gillesありがとう!loadkeysがマッピングkeycode-> keysymとkeysym->エスケープシーケンスの両方を変更することは注目に値します(これは最初私には明らかではありませんでした)。
stewbasic

1
うわー、これは私が今までStackexchangeで見た中で最高の答えの1つでなければなりません-よく組織され、質問に答え、関連するコンテキストを提供し、他の有用な答えを相互参照し、さらに素敵なASCIIアートさえ持っています!
ジョントロン

4

理解できるほど小さいUnixシステムでこれを見たい場合は、Xv6を掘り下げてください。ジョン・ライオンの有名な解説のベースとなったのは、神話上のUnix第6版であり、長い間samizdatとして流通していました。そのコードは、ANSI Cでコンパイルし、マルチプロセッサなどの最新の開発を考慮して修正されました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.