Xlib, ne kadar zor olabilir ki?
Dün müydü, ondan önceki gün müydü hatırlamıyorum, aklıma bir fikir geldi. Mouse ile tıkladığım noktaları bir yere kaydedeyim, bir kaç gün veri topladıktan sonra da scatter plot'unu çizerim, enteresan birşey olur diye düşündüm.
Mouse ile tıklanan noktaları bulmak kısmını Xlib ile yapmak gerekir diye düşündüm, gui kütüphaneleri işimi görmüyordu, çünkü programın pencere oluşturmadan arka planda çalışması, hangi pencere seçili olursa olsun, mouse tıklanma durumunu görebilmesi lazımdı. Aradan bir miktar araştırma süresi geçtikten sonra, #xorg-devel'de şöyle bir muhabbet geçti;
yasar: Hi. I am trying to learn Xlib. Can I use XSelectInput on root window? Because I don't want to create a window, I am only interested in Mouse Events. jcristau: why do you hate yourself that much? anyway, yes.
Ben bu why do you hate yourself that much?
(kendinden niye bu kadar
nefret ediyorsun?) lafına o an tam bir anlam veremedim. Neyse, sorduğum
soru basit. XSelectInput fonksiyonu, bir girdi aygıtını dinlemeye
yarıyor. Ben bunu root pencerede, yani bütün pencerelerin içinde
bulunduğu pencerede kullanabilir miyim diye soruyorum. Aldığım cevap
olumlu, root pencerede buton tıklama olayını dinlemeye çalışıyorum, ama
bir sıkıntı var;
X Error of failed request: BadAccess (attempt to access private resource denied) Major opcode of failed request: 2 (X_ChangeWindowAttributes) Serial number of failed request: 7 Current serial number in output stream: 7
Hmm, BadAccess diye bir hata aldım. Bunun ne olduğunu anlamak için de baya bir zaman ve efor harcadım. Meğersem, tıklama olayını bir pencerede, sadece bir client dinleyebiliyormuş, ve root penceredeki tıklanma olayını da pencere yöneticisi dinliyormuş, ki bu çok mantıklı. Ben bu aşamada, ümitlerimi biraz yitirmiştim aslında, ancak, ButtonRelease (butonu salıverme) olayını aynı pencerede birden fazla client dinleyebildiğini öğrendim. Benim amacım için, tıklanma olayı ile salınma olayı arasında fazla bir fark yoktu, o yüzden işim çok kolay oldu. (Dermişim) Bunu denediğim kodlar şu şekilde;
Evet, yukarıdaki kodda herşey güzel gibi görünüyor. Hata falan da almıyorum. Ama aksi gibi, bir çıktı da almıyorum. Peki neden mi? Hiçbir fikrim yok :)
Aslında yukarıdaki olayları anlatırken, kronolojik sıraya dikkat etmedim. Bu olaylar olurken, aynı zamanda şöyle birşey öğrendim: `It's possible to read XI_RawButtonPress events from the root window if that helps`. Diyor ki, XI_RawButtonPress olayını root pencereden dinleyebilirsin. Peki, bu XI_RawButtonPress ne mi? X input extensions diye bir kütüphane varmış, Bu kütüphane işlenmemiş (raw) olayları dinleyeme izin veriyormuş. Yanlış anlamadıysam, ki yanlış anlamış olma ihtimalim var, bu kütüphaneyi biraz karmaşık ihtiyaçları olan, oyunlar, gibi programlar kullanıyor. Neyse, biraz ileri saralım, ben bu konuda biraz aşama kaydettim, ve root pencereden işlenmemiş tıklanma olaylarını dinleyebilmeyi başardım. En son olarak kullandığım kodlar şu şekilde;
(Yukarıdaki kodlar çok gelişigüzel bir şekilde yazılıp, göstermek amaçlı konulmuştur.)
Bu programı, pencere yöneticisinin oto-başlat listesine ekledim. Malesef, henüz hala XIRawEvent içinden nasıl x ve y koordinatları alınır bilmiyorum, o yüzden sadece tıklanma zamanlarını kaydediyorum. Belki bu verilerden de ilginç bir analiz çıkabilir.
Süreç boyunca olanları daha yakından incelemek isteyenler için, SO sorusu ve
Tüm bunları yazmaya başlamadan önce, aklımda vermek istediğim bir mesaj vardı, galiba açık kaynak dünyasında düzgün ve kapsamlı belgelendirmenin önemi hakkında birşeydi. İyi düşünülmüş, insanları düşünmeye sevk eden birşey olacaktı, ama o kadar yazacak enerjim kalmadı. Sadece hikayemi paylaşmış olmakla yetineceğim. Ve, genç programcılara bir tavsiye, Xlib olayına bulaşmayın.