![]() | English tiếng Việt |
| Xvnkb Vdict Vdesk Misc Contact |
CƠ CHẾ LÀM VIỆC CỦA xvnkb 0.1.xTÁC GIẢ: Đào Hải LâmTHAM KHẢO: X-Window programming "CHẶN" VÀ XỬ LÝ EVENTSCơ chế làm việc của X Server cho phép ta "đăng ký" nhận events gửi
đến mọi window của tất cả các X Applications khác đang làm việc trong
cùng một screen với chương trình của chúng ta. Đây chính là "chìa khoá"
để xvnkb 0.1.x có thể tác động đến các X Apps khác. Để "đăng ký" nhận
events ta dùng function
Trong đó: Sau khi chúng ta đã "đăng ký" nhận events thì event flow sẽ giống như sơ đồ sau:
+--------------+
| X Server |
+------+-------+
|
| events
|
masked |
events |
+------------+-------------+
| |
| |
v v
+-------+ +-------+
| xvnkb | | X app |
+-------+ +-------+
Với cách này, xvnkb có thể đồng thời nhận được tất cả các key events
được gửi tới các X Apps khác. Sau khi xử lý các key events này, nó có
thể tạo ra 1 hoặc nhiều events giả, rồi gửi tới X App đang nhận xử lý
key event (focused X app) bằng cách dùng function
Trong đó:
+--------------+
| X Server |
+------+-------+
|
| events
|
masked |
events |
+------------+-------------+
| |
| |
v v
+-------+ events +-------+
| xvnkb | +----->| X app |
+--+-------+--+ | +-------+
| key | |
| processing |--------+
+-------------+ (XSendEvent)
Như vậy khi user nhập vào "ddoongj" (telex mode), xvnkb sẽ xử lý như sau:
(+) Xem file focuswin.c trong source code của xvnkb để biết thêm chi tiết, các function cần chú ý: VKSendKeyEvent, VKSendKey, VKKeyHandler KIỂM TRA VÀ LẤY FOCUSED WINDOWĐể lấy được focused window, cách đơn giản nhất là định thời (timer) và gọi function XGetInputFocus:
(+) Xem thêm main.c/monitor.c "ĐĂNG KÝ" NHẬN EVENTSVấn đề còn lại là làm sao để có thể lấy được tất cả các window trong screen hiện tại để "đăng ký" nhận key event, đồng thời khi có 1 X App mới được load lên ta phải nhận biết để cập nhật những window mới? Để giải quyết vấn đề thứ nhất ta dung function XQueryTree để lấy tất cả các sub-windows của root window. Sau đó, dùng đệ quy (recursion) để tìm tiếp các sub-windows ở cấp sâu hơn. Cứ với mỗi window tìm được (ngoại trừ root window) ta đều "đăng ký" nhận key events. Với vấn đề thứ hai, vì khi có 1 window mới hiện ra thì root window hoặc focused window (nếu đó là 1 sub-window của chương trình đang chạy) sẽ nhận được MapNotify event. Vậy ta chỉ việc "đăng ký" nhận thêm các MapNotify events và chỉ cần cập nhật lại các sub-windows của window mới hiện ra như đã làm ở trên. (+) Xem file winctrl.c trong source code của xvnkb 0.1.x để biết thêm chi tiết, xem focuswin.c phần process events MapNofity NHẬN XÉTVới cách làm việc như trên, thực chất xvnkb không chặn được các events gửi tới focused window nào đó, nó chỉ đồng thời nhận được 1 bản copy của events, sau khi "nhận dạng" và xử lý nó sẽ gửi các events phù hợp đến focused window, nhằm thay đổi và tạo ra chuỗi ký tự nhập phù hợp. HẠN CHẾ
| |||