Làm thế nào để nhập liệu bàn phím và đầu ra văn bản làm việc?


85

Giả sử tôi nhấn Aphím trong trình soạn thảo văn bản và thao tác này sẽ chèn ký tự avào tài liệu và hiển thị trên màn hình. Tôi biết ứng dụng soạn thảo không giao tiếp trực tiếp với phần cứng (có kernel và nội dung ở giữa), vậy chuyện gì đang xảy ra bên trong máy tính của tôi?

Câu trả lời:


100

Có một số kịch bản khác nhau; Tôi sẽ mô tả những cái phổ biến nhất. Các sự kiện vĩ mô kế tiếp là:

  1. Đầu vào: sự kiện nhấn phím được truyền từ phần cứng bàn phím đến ứng dụng.
  2. Xử lý: ứng dụng quyết định rằng vì phím Ađược nhấn, nó phải hiển thị ký tự a.
  3. Đầu ra: ứng dụng đưa ra thứ tự hiển thị atrên màn hình.

Ứng dụng GUI

Giao diện người dùng đồ họa tiêu chuẩn thực tế của các hệ thống unix là X Window System , thường được gọi là X11 vì nó ổn định trong phiên bản thứ 11 của giao thức cốt lõi giữa các ứng dụng và máy chủ hiển thị. Một chương trình được gọi là máy chủ X nằm giữa nhân hệ điều hành và các ứng dụng; nó cung cấp các dịch vụ bao gồm hiển thị các cửa sổ trên màn hình và truyền các lần nhấn phím đến cửa sổ có tiêu điểm.

Đầu vào

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

Đầu tiên, thông tin về phím bấm và phím phát hành được truyền từ bàn phím đến máy tính và bên trong máy tính. Các chi tiết phụ thuộc vào loại phần cứng. Tôi sẽ không tập trung hơn vào phần này vì thông tin vẫn giữ nguyên trong suốt phần này của chuỗi: một khóa nhất định đã được nhấn hoặc phát hành.

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

Khi một sự kiện phần cứng xảy ra, CPU sẽ kích hoạt một ngắt , khiến một số mã trong kernel thực thi. Mã này phát hiện ra rằng sự kiện phần cứng là một lần nhấn phím hoặc phát hành khóa đến từ bàn phím và ghi lại mã quét xác định khóa.

Máy chủ X đọc các sự kiện đầu vào thông qua một tệp thiết bị , ví dụ như /dev/input/eventNNNtrên Linux (trong đó NNN là một số). Bất cứ khi nào có một sự kiện, hạt nhân báo hiệu rằng có dữ liệu để đọc từ thiết bị đó. Tệp thiết bị truyền các sự kiện lên / xuống của khóa bằng mã quét, có thể giống hoặc không giống với giá trị được truyền bởi phần cứng (hạt nhân có thể dịch mã quét từ giá trị phụ thuộc bàn phím sang giá trị chung và Linux không sẽ không truyền lại mã quét mà nó không biết ).

X gọi mã quét mà nó đọc mã khóa . Máy chủ X duy trì một bảng có thể dịch mã khóa thành các từ khóa (viết tắt của biểu tượng khóa chính là Cameron ). Mã phím là số, trong khi keysyms là những cái tên như A, aacute, F1, KP_Add, Control_L, ... Các keysym có thể khác nhau tùy thuộc vào các phím modifier được ép ( Shift, Ctrl, ...).

Có hai cơ chế để định cấu hình ánh xạ từ mã khóa sang mã khóa:

  • xmodmap là cơ chế truyền thống. Nó là một mã khóa ánh xạ bảng đơn giản vào một danh sách các từ khóa (không thay đổi, thay đổi, khác).
  • XKB là một cơ chế mạnh hơn, nhưng phức tạp hơn với sự hỗ trợ tốt hơn cho nhiều bộ sửa đổi, đặc biệt là cho cấu hình ngôn ngữ kép, trong số các cơ chế khác.

Các ứng dụng kết nối với máy chủ X và nhận thông báo khi nhấn phím trong khi cửa sổ của ứng dụng đó có tiêu điểm. Thông báo chỉ ra rằng một keyym nhất định đã được nhấn hoặc phát hành cũng như những gì sửa đổi hiện đang được nhấn. Bạn có thể thấy các từ khóa bằng cách chạy chương trình xevtừ một thiết bị đầu cuối. Những gì ứng dụng làm với thông tin là tùy thuộc vào nó; một số ứng dụng có các ràng buộc chính cấu hình.

Trong một cấu hình thông thường, khi bạn nhấn phím có nhãn Akhông có sửa đổi, điều này sẽ gửi keyym ađến ứng dụng; nếu ứng dụng ở chế độ bạn đang nhập văn bản, ứng dụng này sẽ chèn ký tự a.

Mối quan hệ của bố cục bàn phím và xmodmap đi sâu vào chi tiết hơn về đầu vào bàn phím. Làm thế nào để các sự kiện chuột làm việc trong linux? đưa ra một cái nhìn tổng quan về đầu vào chuột ở các cấp thấp hơn.

Đầu ra

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

Có hai cách để hiển thị một nhân vật.

Xem mục đích của các loại phông chữ XWindows khác nhau là gì? để thảo luận về kết xuất văn bản phía máy khách và phía máy chủ trong X11.

Điều gì xảy ra giữa máy chủ X và Bộ xử lý đồ họa (bộ xử lý trên thẻ video) phụ thuộc rất nhiều vào phần cứng. Các hệ thống đơn giản có máy chủ X vẽ trong vùng nhớ được gọi là bộ đệm khung , GPU được chọn để hiển thị. Các hệ thống tiên tiến như được tìm thấy trên bất kỳ PC hoặc điện thoại thông minh thế kỷ 21 nào cho phép GPU thực hiện một số thao tác trực tiếp để có hiệu suất tốt hơn. Cuối cùng, GPU truyền pixel nội dung màn hình theo pixel từng phần của giây đến màn hình.

Ứng dụng chế độ văn bản, chạy trong một thiết bị đầu cuối

Nếu trình soạn thảo văn bản của bạn là một ứng dụng chế độ văn bản đang chạy trong một thiết bị đầu cuối, thì đó là thiết bị đầu cuối là ứng dụng cho mục đích của phần trên. Trong phần này, tôi giải thích giao diện giữa ứng dụng chế độ văn bản và thiết bị đầu cuối. Đầu tiên tôi mô tả trường hợp của một trình giả lập thiết bị đầu cuối chạy dưới X11. Sự khác biệt chính xác giữa 'thiết bị đầu cuối', 'vỏ', 'tty' và 'bàn điều khiển' là gì? có thể là nền tảng hữu ích ở đây. Sau khi đọc điều này, bạn có thể muốn đọc chi tiết hơn nhiều về trách nhiệm của từng thành phần Pseudo-Terminal (PTY) (phần mềm, phía chủ, bên nô lệ) là gì?

Đầu vào

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

Trình giả lập thiết bị đầu cuối nhận các sự kiện như Leftđã được nhấn trong khi Shiftxuống xuống. Giao diện giữa trình giả lập thiết bị đầu cuối và ứng dụng chế độ văn bản là một thiết bị đầu cuối giả (pty) , một thiết bị ký tự truyền các byte. Khi trình giả lập thiết bị đầu cuối nhận được một sự kiện nhấn phím, nó sẽ biến đổi nó thành một hoặc nhiều byte mà ứng dụng sẽ đọc từ thiết bị pty.

Các ký tự có thể in bên ngoài phạm vi ASCII được truyền dưới dạng một hoặc nhiều byte tùy thuộc vào ký tự và mã hóa . Ví dụ, trong mã hóa UTF-8 của bộ tự Unicode , các ký tự trong phạm vi ASCII được mã hóa dưới dạng một byte, trong khi các ký tự bên ngoài phạm vi đó được mã hóa thành nhiều byte.

Các phím bấm tương ứng với một phím chức năng hoặc một ký tự có thể in được với các sửa đổi, chẳng hạn như Ctrlhoặc Altđược gửi dưới dạng một chuỗi thoát . Các chuỗi thoát thường bao gồm thoát ký tự (giá trị byte 27 = 0x1B = \033, đôi khi được biểu thị bằng ^[hoặc \e) theo sau là một hoặc nhiều ký tự có thể in được. Một vài khóa hoặc tổ hợp phím có một ký tự điều khiển tương ứng với chúng trong các bảng mã dựa trên ASCII (gần như tất cả chúng được sử dụng ngày nay, bao gồm Unicode): Ctrl+ lettermang lại giá trị ký tự trong phạm vi 1 Biệt26, Esclà ký tự thoát thấy ở trên và cũng giống như Ctrl+ [, Tabgiống như Ctrl+ I,Returngiống như Ctrl+ M, v.v.

Các thiết bị đầu cuối khác nhau gửi các chuỗi thoát khác nhau cho một tổ hợp phím hoặc khóa nhất định. May mắn thay, điều ngược lại là không đúng: đưa ra một chuỗi, trong thực tế có nhiều nhất một tổ hợp khóa mà nó mã hóa. Một ngoại lệ là ký tự 127 = 0x7f = \0177thường Backspacenhưng đôi khi Delete.

Trong một thiết bị đầu cuối, nếu bạn gõ Ctrl+ Vtheo sau là tổ hợp phím, điều này sẽ chèn byte đầu tiên của chuỗi thoát khỏi tổ hợp phím theo nghĩa đen. Vì các chuỗi thoát thường chỉ bao gồm các ký tự có thể in được sau ký tự đầu tiên, nên trình tự này sẽ chèn toàn bộ chuỗi thoát theo nghĩa đen. Xem bảng ràng buộc chính? cho một cuộc thảo luận về zsh trong bối cảnh này.

Thiết bị đầu cuối có thể truyền cùng một chuỗi thoát cho một số kết hợp sửa đổi (ví dụ: nhiều thiết bị đầu cuối truyền một ký tự không gian cho cả hai SpaceShift+ Space; xterm có chế độ để phân biệt các kết hợp sửa đổi nhưng các thiết bị đầu cuối dựa trên thư viện vte phổ biến thì không ). Một vài khóa hoàn toàn không được truyền, ví dụ các phím bổ trợ hoặc các phím kích hoạt liên kết của trình giả lập thiết bị đầu cuối (ví dụ: lệnh sao chép hoặc dán).

Tùy thuộc vào ứng dụng để dịch các chuỗi thoát thành các tên khóa tượng trưng nếu nó rất mong muốn.

Đầu ra

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

Đầu ra khá đơn giản hơn đầu vào. Nếu ứng dụng xuất ký tự cho tệp thiết bị pty, trình giả lập thiết bị đầu cuối sẽ hiển thị nó ở vị trí con trỏ hiện tại. (Trình giả lập thiết bị đầu cuối duy trì vị trí con trỏ và cuộn nếu con trỏ nằm dưới đáy màn hình.) Ứng dụng cũng có thể xuất các chuỗi thoát (chủ yếu bắt đầu bằng ^[hoặc ^]) để báo cho thiết bị đầu cuối thực hiện các hành động như di chuyển con trỏ, thay đổi các thuộc tính văn bản (màu sắc, đậm, khắc) hoặc xóa một phần của màn hình.

Trình tự thoát được hỗ trợ bởi trình giả lập thiết bị đầu cuối được mô tả trong cơ sở dữ liệu termcap hoặc terminfo . Hầu hết các trình giả lập thiết bị đầu cuối hiện nay đều được liên kết khá chặt chẽ với xterm . Xem Tài liệu về các biến LESS_TERMCAP_ *? để thảo luận lâu hơn về cơ sở dữ liệu thông tin về khả năng của thiết bị đầu cuối và Làm thế nào để ngăn con trỏ nhấp nháytôi có thể đặt màu thiết bị đầu cuối của máy cục bộ của mình để sử dụng màu của máy tôi ssh không? cho một số ví dụ sử dụng.

Ứng dụng đang chạy trong bảng điều khiển văn bản

Nếu ứng dụng đang chạy trực tiếp trong bảng điều khiển văn bản, tức là một thiết bị đầu cuối được cung cấp bởi kernel chứ không phải bởi một ứng dụng giả lập thiết bị đầu cuối, các nguyên tắc tương tự sẽ được áp dụng. Giao diện giữa thiết bị đầu cuối và ứng dụng vẫn là một luồng byte truyền các ký tự, với các phím và lệnh đặc biệt được mã hóa thành các chuỗi thoát.

Ứng dụng từ xa, truy cập qua mạng

Ứng dụng văn bản từ xa

Nếu bạn chạy một chương trình trên một máy từ xa, ví dụ như qua SSH , thì giao thức truyền thông mạng sẽ chuyển tiếp dữ liệu ở mức pty.

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

Điều này chủ yếu là minh bạch, ngoại trừ đôi khi cơ sở dữ liệu thiết bị đầu cuối từ xa có thể không biết tất cả các khả năng của thiết bị đầu cuối cục bộ.

Ứng dụng X11 từ xa

Giao thức giao tiếp giữa các ứng dụng mà máy chủ tự nó là một luồng byte có thể được gửi qua một giao thức mạng như SSH.

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

Điều này chủ yếu là trong suốt, ngoại trừ một số tính năng tăng tốc như giải mã phim và kết xuất 3D yêu cầu giao tiếp trực tiếp giữa ứng dụng và màn hình không khả dụng.


Không hoàn toàn chắc chắn, nhưng vì câu trả lời thường khá chi tiết, tôi tự hỏi liệu phần "Ứng dụng đang chạy trong bảng điều khiển văn bản" có thể không có tính năng như những thứ như man 5 keymapsđược sử dụng để dịch keycodessang scancodes. Mặc dù như đã đề cập chủ yếu tương tự nhưng nó là một bộ công cụ / chương trình hoàn toàn khác và điều này có thể có giá trị hơn một số hiểu biết. Bên cạnh đó, câu trả lời là +1 và tuyệt vời vì các câu hỏi liên quan được nhúng.
nhân

Tôi đã tìm thấy PgUpCtrl+PgUpkhông thể phân biệt được trong tty1 (TERM = linux). Các keyym -> ánh xạ trình tự điều khiển có thể được cấu hình không?
stewbasic

@stewbasic Có, với một sơ đồ được tải bởi loadkeys. Tìm kiếm các câu hỏi được gắn thẻ bảng điều khiển linux bố trí bàn phím .
Gilles

@Gilles cảm ơn! Điều đáng chú ý là các loadkey thay đổi cả mã khóa ánh xạ -> keyym và keyymymymymymym> - trình tự thoát (điều này ban đầu không rõ ràng đối với tôi).
stewbasic

1
Ồ, đây phải là một trong những câu trả lời hay nhất tôi từng thấy trên Stackexchange - được tổ chức tốt, trả lời câu hỏi, cung cấp ngữ cảnh có liên quan, tham khảo chéo các câu trả lời hữu ích khác và thậm chí có nghệ thuật ASCII tuyệt vời!
Johntron

4

Nếu bạn muốn thấy điều này trong một hệ thống Unix đủ nhỏ để có thể hiểu được, hãy đào sâu vào Xv6 . Nó ít nhiều là phiên bản Unix thứ 6 huyền thoại đã trở thành nền tảng của bình luận nổi tiếng của John Lion , được lưu hành từ lâu như samizdat. Mã của nó đã được làm lại để biên dịch theo ANSI C và đưa các phát triển hiện đại, như đa bộ xử lý vào tài khoản.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.