สมมติว่าฉันกดAปุ่มในตัวแก้ไขข้อความและสิ่งนี้แทรกตัวละครa
ในเอกสารและแสดงบนหน้าจอ ฉันรู้ว่าแอปพลิเคชันตัวแก้ไขไม่ได้สื่อสารโดยตรงกับฮาร์ดแวร์ (มีเคอร์เนลและสิ่งต่าง ๆ อยู่ระหว่างนั้น) ดังนั้นสิ่งที่เกิดขึ้นภายในคอมพิวเตอร์ของฉัน
สมมติว่าฉันกดAปุ่มในตัวแก้ไขข้อความและสิ่งนี้แทรกตัวละครa
ในเอกสารและแสดงบนหน้าจอ ฉันรู้ว่าแอปพลิเคชันตัวแก้ไขไม่ได้สื่อสารโดยตรงกับฮาร์ดแวร์ (มีเคอร์เนลและสิ่งต่าง ๆ อยู่ระหว่างนั้น) ดังนั้นสิ่งที่เกิดขึ้นภายในคอมพิวเตอร์ของฉัน
คำตอบ:
มีหลายสถานการณ์ที่แตกต่างกัน ฉันจะอธิบายสิ่งที่พบบ่อยที่สุด เหตุการณ์ที่เกิดขึ้นอย่างต่อเนื่องคือ:
a
a
บนหน้าจออินเทอร์เฟซผู้ใช้แบบกราฟิกมาตรฐานโดยพฤตินัยของระบบ unix คือX Window Systemซึ่งมักเรียกว่า X11 เนื่องจากมันเสถียรในโปรโตคอลหลักรุ่นที่ 11 ระหว่างแอพพลิเคชันและเซิร์ฟเวอร์การแสดงผล โปรแกรมที่เรียกว่าเซิร์ฟเวอร์ X ตั้งอยู่ระหว่างเคอร์เนลระบบปฏิบัติการและแอพพลิเคชัน มันให้บริการรวมถึงการแสดงหน้าต่างบนหน้าจอและกดปุ่มส่งสัญญาณไปยังหน้าต่างที่มีโฟกัส
+----------+ +-------------+ +-----+
| keyboard |------------->| motherboard |-------->| CPU |
+----------+ +-------------+ +-----+
USB, PS/2, … PCI, …
key down/up
ขั้นแรกข้อมูลเกี่ยวกับการกดปุ่มและการปล่อยปุ่มจะถูกส่งจากคีย์บอร์ดไปยังคอมพิวเตอร์และภายในคอมพิวเตอร์ รายละเอียดขึ้นอยู่กับประเภทของฮาร์ดแวร์ ฉันจะไม่อาศัยอยู่ในส่วนนี้มากขึ้นเพราะข้อมูลยังคงเหมือนเดิมตลอดส่วนนี้ของโซ่: มีการกดหรือปล่อยคีย์ที่แน่นอน
+--------+ +----------+ +-------------+
-------->| kernel |------->| X server |--------->| application |
+--------+ +----------+ +-------------+
interrupt scancode keysym
=keycode +modifiers
เมื่อมีเหตุการณ์ฮาร์ดแวร์เกิดขึ้น CPU จะทริกเกอร์การขัดจังหวะซึ่งทำให้รหัสบางอย่างในเคอร์เนลทำงาน รหัสนี้ตรวจพบว่าเหตุการณ์ฮาร์ดแวร์เป็นการกดปุ่มหรือการเปิดตัวคีย์ที่มาจากแป้นพิมพ์และบันทึกรหัสการสแกนซึ่งระบุรหัส
เซิร์ฟเวอร์ X อ่านเหตุการณ์อินพุตผ่านไฟล์อุปกรณ์ตัวอย่างเช่น/dev/input/eventNNN
บน Linux (โดยที่ NNN คือตัวเลข) เมื่อใดก็ตามที่มีเหตุการณ์เคอร์เนลจะส่งสัญญาณว่ามีข้อมูลที่อ่านจากอุปกรณ์นั้น ไฟล์อุปกรณ์ส่งเหตุการณ์สำคัญขึ้น / ลงด้วยรหัสสแกนซึ่งอาจหรืออาจจะไม่เหมือนกันกับค่าที่ส่งโดยฮาร์ดแวร์ (เคอร์เนลอาจแปลรหัสสแกนจากค่าขึ้นอยู่กับคีย์บอร์ดเป็นค่าทั่วไปและ Linux ไม่ ไม่ต้องส่งรหัสสแกนซ้ำที่ไม่ทราบ )
X เรียกสแกนรหัสว่ามันอ่านkeycode เซิร์ฟเวอร์ X เก็บรักษาตารางที่แปลรหัสคีย์เป็นkeysyms (ย่อมาจาก "สัญลักษณ์สัญลักษณ์") การพิมพ์ซ้ำเป็นตัวเลขในขณะที่ keysyms มีชื่อเช่นA
, aacute
, F1
, KP_Add
, Control_L
, ... ความ keysym อาจแตกต่างกันขึ้นอยู่กับคีย์ตัวปรับแต่งถูกกด ( Shift, Ctrl, ... )
มีสองกลไกในการกำหนดค่าการแมปจากรหัสคีย์เป็น keysyms:
แอปพลิเคชันเชื่อมต่อกับเซิร์ฟเวอร์ X และรับการแจ้งเตือนเมื่อกดปุ่มในขณะที่หน้าต่างของแอปพลิเคชันนั้นมีโฟกัส การแจ้งเตือนบ่งชี้ว่ามีการกดหรือปล่อย keysym ที่แน่นอนรวมถึงตัวดัดแปลงใดที่ถูกกดในปัจจุบัน คุณสามารถดู keysyms ได้โดยการรันโปรแกรมxev
จากเทอร์มินัล สิ่งที่แอปพลิเคชันทำกับข้อมูลนั้นขึ้นอยู่กับมัน แอปพลิเคชั่นบางตัวมีการเชื่อมโยงคีย์ที่กำหนดค่าได้
ในการกำหนดค่าทั่วไปเมื่อคุณกดปุ่มที่Aไม่มีป้ายโมดิฟายเออร์สิ่งนี้จะส่ง keysym a
ไปยังแอปพลิเคชัน a
ถ้าสมัครอยู่ในโหมดที่คุณกำลังพิมพ์ข้อความนี้แทรกตัวอักษร
ความสัมพันธ์ของรูปแบบแป้นพิมพ์และ xmodmapมีรายละเอียดเพิ่มเติมเกี่ยวกับการป้อนข้อมูลด้วยแป้นพิมพ์ เหตุการณ์เมาส์ทำงานใน linux อย่างไร ให้ภาพรวมของการป้อนข้อมูลเมาส์ในระดับที่ต่ำกว่า
+-------------+ +----------+ +-----+ +---------+
| application |------->| X server |---····-->| GPU |-------->| monitor |
+-------------+ +----------+ +-----+ +---------+
text or varies VGA, DVI,
image HDMI, …
มีสองวิธีในการแสดงอักขระ
ดูวัตถุประสงค์ของแบบอักษร XWindows ชนิดต่าง ๆ คืออะไร สำหรับการอภิปรายของการสร้างการแสดงผลข้อความฝั่งไคลเอ็นต์และฝั่งเซิร์ฟเวอร์ภายใต้ X11
เกิดอะไรขึ้นระหว่างเซิร์ฟเวอร์ X และหน่วยประมวลผลกราฟิก (โปรเซสเซอร์บนการ์ดจอ) ขึ้นอยู่กับฮาร์ดแวร์เป็นอย่างมาก ระบบที่เรียบง่ายมีเซิร์ฟเวอร์ X วาดอยู่ในขอบเขตหน่วยความจำที่เรียกว่าframebufferซึ่ง GPU เลือกขึ้นมาเพื่อแสดงผล ระบบขั้นสูงเช่นที่พบในพีซีหรือสมาร์ทโฟนศตวรรษที่ 21 อนุญาตให้ GPU ดำเนินการบางอย่างโดยตรงเพื่อประสิทธิภาพที่ดีขึ้น ในท้ายที่สุด GPU ส่งพิกเซลเนื้อหาของหน้าจอเป็นพิกเซลทุกเสี้ยววินาทีไปยังจอภาพ
หากเท็กซ์เอดิเตอร์ของคุณเป็นแอ็พพลิเคชันโหมดข้อความที่รันในเทอร์มินัลแสดงว่าเป็นเทอร์มินัลซึ่งเป็นแอปพลิเคชันสำหรับจุดประสงค์ของส่วนด้านบน ในส่วนนี้ฉันอธิบายอินเตอร์เฟสระหว่างแอปพลิเคชันโหมดข้อความและเทอร์มินัล ก่อนอื่นฉันอธิบายกรณีของเทอร์มินัลอีมูเลเตอร์ที่ทำงานภายใต้ X11 ความแตกต่างที่แน่นอนระหว่าง 'terminal', 'shell', 'tty' และ 'console' คืออะไร? อาจเป็นพื้นหลังที่เป็นประโยชน์ที่นี่ หลังจากอ่านสิ่งนี้แล้วคุณอาจต้องการอ่านรายละเอียดเพิ่มเติมสิ่งที่เป็นความรับผิดชอบของแต่ละองค์ประกอบ Pseudo-Terminal (PTY) (ซอฟต์แวร์ด้านหลักด้านทาส)
+-------------------+ +-------------+
----->| terminal emulator |-------------->| application |
+-------------------+ +-------------+
keysym character or
escape sequence
เทอร์มินัลอีมูเลเตอร์รับเหตุการณ์เช่น“ Left
ถูกกดขณะที่ไม่Shift
ทำงาน” อินเตอร์เฟสระหว่างเทอร์มินัลอีมูเลเตอร์และแอปพลิเคชันโหมดข้อความคือpseudo-terminal (pty)ซึ่งเป็นอุปกรณ์ตัวอักษรที่ส่งไบต์ เมื่อเทอร์มินัลอีมูเลเตอร์ได้รับเหตุการณ์การกดปุ่มมันจะแปลงสิ่งนี้ให้เป็นหนึ่งไบต์หรือมากกว่านั้นซึ่งแอปพลิเคชันจะอ่านจากอุปกรณ์ pty
ตัวอักษรพิมพ์นอกช่วง ASCII จะถูกส่งเป็นหนึ่งหรือมากกว่าหนึ่งไบต์ขึ้นอยู่กับตัวละครและการเข้ารหัส ตัวอย่างเช่นในการเข้ารหัส UTF-8ของชุดอักขระ Unicodeอักขระในช่วงASCIIจะถูกเข้ารหัสเป็นไบต์เดียวในขณะที่อักขระที่อยู่นอกช่วงนั้นจะถูกเข้ารหัสเป็นหลายไบต์
กดปุ่มที่สอดคล้องกับคีย์ฟังก์ชันหรือตัวอักษรที่พิมพ์ได้มีการปรับเปลี่ยนเช่นCtrlหรือAltจะส่งเป็นลำดับหนี โดยทั่วไปแล้วลำดับ Escape ประกอบด้วยอักขระescape (ค่าไบต์ 27 = 0x1B = \033
บางครั้งแทน^[
หรือ\e
) ตามด้วยอักขระที่พิมพ์ได้หนึ่งตัวหรือมากกว่า คีย์หรือชุดคีย์สองสามตัวมีอักขระควบคุมที่สอดคล้องกับพวกเขาในการเข้ารหัสตาม ASCII (ซึ่งค่อนข้างมากของพวกมันทั้งหมดที่ใช้อยู่ในปัจจุบันรวมถึง Unicode): Ctrl+ letterให้ค่าอักขระในช่วง 1-26 Escคืออักขระ escape เห็นข้างต้นและยังเป็นเช่นเดียวกับCtrl+ [, TabเหมือนกับCtrl+ I,ReturnเหมือนกับCtrl+ Mฯลฯ
เทอร์มินัลที่แตกต่างกันส่ง escape sequences ที่แตกต่างกันสำหรับคีย์ที่ระบุหรือคีย์ผสม โชคดีที่การสนทนาไม่เป็นความจริง: เนื่องจากมีการเรียงลำดับแล้วในทางปฏิบัติจะมีการรวมคีย์หนึ่งชุดที่เข้ารหัส หนึ่งยกเว้นเป็นตัวละคร 127 = = 0x7F \0177
ซึ่งมักจะเป็นแต่บางครั้งBackspaceDelete
ในเทอร์มินัลถ้าคุณพิมพ์Ctrl+ Vตามด้วยชุดคีย์นี้จะแทรกไบต์แรกของลำดับ escape จากชุดคีย์อย่างแท้จริง เนื่องจากโดยทั่วไปแล้ว escape sequences จะประกอบด้วยอักขระที่พิมพ์ได้หลังจากตัวแรกเท่านั้นนี่จะเป็นการแทรกลำดับ escape ทั้งหมดอย่างแท้จริง ดูตารางการผูกกุญแจ? สำหรับการสนทนาของ zsh ในบริบทนี้
ขั้วอาจส่งลำดับหนีเหมือนกันสำหรับการผสมปรับปรุงบางอย่าง (เช่นหลายขั้วส่งอักขระช่องว่างสำหรับทั้งสองSpaceและShift+ Space; xterm มีโหมดที่จะแยกแยะความแตกต่างรวมกันปรับปรุงแต่ขั้วบนพื้นฐานของห้องสมุด VTE นิยมทำไม่ได้ ) ไม่กี่คีย์จะไม่ถูกส่งเลยตัวอย่างเช่นปุ่มตัวดัดแปลงหรือคีย์ที่ทริกเกอร์การโยงเทอร์มินัลอีมูเลเตอร์ (เช่นคำสั่งคัดลอกหรือวาง)
มันขึ้นอยู่กับแอพพลิเคชั่นในการแปล escape sequences เป็นชื่อคีย์สัญลักษณ์หากต้องการ
+-------------+ +-------------------+
| application |-------------->| terminal emulator |--->
+-------------+ +-------------------+
character or
escape sequence
เอาต์พุตค่อนข้างง่ายกว่าอินพุต หากแอ็พพลิเคชันส่งอักขระไปยังไฟล์อุปกรณ์ pty เทอร์มินัลอีมูเลเตอร์จะแสดงที่ตำแหน่งเคอร์เซอร์ปัจจุบัน (เทอร์มินัลอีมูเลเตอร์รักษาตำแหน่งเคอร์เซอร์และเลื่อนถ้าเคอร์เซอร์จะอยู่ด้านล่างของหน้าจอ) แอปพลิเคชันยังสามารถส่งออกลำดับหนี (ส่วนใหญ่เริ่มต้นด้วย^[
หรือ^]
) เพื่อบอกเทอร์มินัลเพื่อดำเนินการต่าง ๆ เช่นการย้ายเคอร์เซอร์ การเปลี่ยนคุณสมบัติข้อความ (สี, ตัวหนา, ... ) หรือการลบส่วนหนึ่งของหน้าจอ
Escape sequences ที่สนับสนุนโดยเทอร์มินัลอีมูเลเตอร์ได้อธิบายไว้ในฐานข้อมูลtermcapหรือterminfo ส่วนใหญ่จำลอง terminal ในปัจจุบันมีค่อนข้างใกล้ชิดกับxterm ดูเอกสารประกอบเกี่ยวกับตัวแปร LESS_TERMCAP_ *? สำหรับการอภิปรายนานขึ้นของฐานข้อมูลความสามารถของเทอร์มินัลและวิธีหยุดเคอร์เซอร์จากการกระพริบและฉันสามารถตั้งค่าสีเทอร์มินัลของเครื่องท้องถิ่นของฉันให้ใช้สีของเครื่องที่ฉัน ssh เข้าไปได้หรือไม่? สำหรับตัวอย่างการใช้งานบางอย่าง
หากแอปพลิเคชันทำงานโดยตรงในคอนโซลข้อความเช่นเทอร์มินัลที่เตรียมไว้โดยเคอร์เนลแทนที่จะใช้แอปพลิเคชันเทอร์มินัลอีมูเลเตอร์จะใช้หลักการเดียวกันนี้ อินเตอร์เฟสระหว่างเทอร์มินัลและแอ็พพลิเคชันยังคงเป็นสตรีมไบต์ที่ส่งอักขระโดยใช้คีย์พิเศษและคำสั่งที่เข้ารหัสเป็นลำดับ escape
หากคุณรันโปรแกรมบนเครื่องระยะไกลเช่นผ่านSSHโปรโตคอลการสื่อสารเครือข่ายจะถ่ายทอดข้อมูลในระดับ pty
+-------------+ +------+ +-----+ +----------+
| application |<--------->| sshd |<--------->| ssh |<--------->| terminal |
+-------------+ +------+ +-----+ +----------+
byte stream byte stream byte stream
(char/seq) over TCP/… (char/seq)
นี่คือส่วนใหญ่โปร่งใสยกเว้นว่าบางครั้งฐานข้อมูลสถานีระยะไกลอาจไม่ทราบความสามารถทั้งหมดของสถานีท้องถิ่น
โปรโตคอลการสื่อสารระหว่างแอปพลิเคชันที่เซิร์ฟเวอร์เป็นตัวเองเป็นไบต์สตรีมที่สามารถส่งผ่านโปรโตคอลเครือข่ายเช่น SSH
+-------------+ +------+ +-----+ +----------+
| application |<---------->| sshd |<------>| ssh |<---------->| X server |
+-------------+ +------+ +-----+ +----------+
X11 protocol X11 over X11 protocol
TCP/…
สิ่งนี้ส่วนใหญ่โปร่งใสยกเว้นว่าคุณลักษณะการเร่งความเร็วบางอย่างเช่นการถอดรหัสภาพยนตร์และการเรนเดอร์ 3D ที่ต้องมีการสื่อสารโดยตรงระหว่างแอปพลิเคชันและจอแสดงผลจะไม่สามารถใช้ได้
PgUp
และCtrl+PgUp
แยกไม่ออกใน tty1 (TERM = linux) การแม็พ keysym -> control สามารถกำหนดค่าได้หรือไม่?
หากคุณต้องการที่จะเห็นสิ่งนี้ในระบบยูนิกซ์ที่มีขนาดเล็กพอที่จะเข้าใจขุดลงไปในXv6 มันเป็นตำนาน Unix รุ่นที่ 6 มากหรือน้อยที่กลายเป็นฐานของคำวิจารณ์ที่มีชื่อเสียงของ John Lion ที่มีมายาวนานราวกับ samizdat รหัสของมันถูกทำใหม่เพื่อคอมไพล์ภายใต้ ANSI C และนำการพัฒนาที่ทันสมัยเช่นมัลติโปรเซสเซอร์เข้าบัญชี
man 5 keymaps
จะใช้สำหรับการแปลไปkeycodes
scancodes
ในขณะที่กล่าวถึงคล้ายกันโดยทั่วไป แต่ก็เป็นชุดเครื่องมือ / โปรแกรมที่แตกต่างกันโดยสิ้นเชิง ถัดจากนั้นคำตอบคือ +1 และยอดเยี่ยมเนื่องจากคำถามที่เกี่ยวข้องที่ฝังอยู่