View Single Post
Old 08-17-2007, 07:16 PM   #1
jharker
Developer
jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.jharker could sell banana peel slippers to a Deveel.
 
Posts: 345
Karma: 3473
Join Date: Apr 2007
Location: Brooklyn, NY, USA
Device: iRex iLiad v1, Blackberry Tour, Kindle DX, iPad.
Understanding the ContentLister

Since the first step in changing (or replacing) something is understanding what it does, I thought I would start a thread about what the contentLister does.

I originally looked into this because I wanted to understand how button presses are handled by the iLiad's software. Now that I've learned a little bit, I've seen something surprising:

It seems that the contentLister does a LOT more than just display directories. I wouldn't be surprised if the contentLister does a large part of the job of running the iLiad. I strongly suspect that the contentLister actually functions as a keyboard driver for the iLiad's buttons (including the power button!). But I might be wrong about all of this.

Here's what I did:

First, I made a slightly modified version of iPDF. In this version, every keypress seen by iPDF is written to a log file. Using this I've been able to determine the GTK+ keycodes for:
  • forward pageturn
  • long forward pageturn
  • backward pageturn
  • long backward pageturn
  • up arrow and long up arrow
  • dot and long dot
  • down arrow and long down arrow
  • the "escape" button (upper left button), which quits the program
However, iPDF does NOT register or record keypresses for the "news", "books", "docs", or "notes" buttons, or for the menu button (the button just under the "escape" button).

I wanted to learn what happens when those buttons are pressed, and where the signals go. My first guess was to that the contentLister was intercepting those keypresses from X...

So, I wanted to learn what happens when we run the contentLister. I set up an ethernet connection to my iLiad and ran DropBear, then used ssh to log in as root. All of the following was done on the command line while logged in to the iLiad. It's possible that some error messages are a result of that.

First, I killed the old contentLister. Then, I had to define DISPLAY so that the new contentLister would know where the display was, then I called the contentLister, just as it's called by start.sh during boot:

Code:
# killall contentLister
# export DISPLAY=:0
# /usr/bin/contentLister --sync &

(CL_E)control.c:344,ctrl_read_configfile() cannot read [CONTENTLISTER] [doc_signing] - Key file does not have key 'doc_signing' [3]
(CL_E)erConnect.c:68,erConnectInit() Lock the connect mutex
(CL_E)metadataStoreManager.c:977,recreateArchives() Can not create directory /mnt/free/newspapers!
(CL_E)metadataStoreManager.c:988,recreateArchives() Can not create directory /mnt/free/books!
(CL_E)metadataStoreManager.c:999,recreateArchives() Can not create directory /mnt/free/documents!
(CL_E)metadataStoreManager.c:1010,recreateArchives() Can not create directory /mnt/free/notes!
(W)eripc.c:37,erIpcInitServer() Version: 256

(W)eripc.c:76,erIpcInitServer() Bound successfully to 127.0.0.1:50070.
(E)erregcommon.c:138,erRegGetExtInfoFromMemory() theExtInfo->iconlocation - Key file does not have key 'ari' [3]
(E)erregcommon.c:138,erRegGetExtInfoFromMemory() theExtInfo->iconlocation - Key file does not have key 'ARI' [3]
(E)erregcommon.c:138,erRegGetExtInfoFromMemory() theExtInfo->iconlocation - Key file does not have key 'sh' [3]
(E)erregcommon.c:138,erRegGetExtInfoFromMemory() theExtInfo->iconlocation - Key file does not have key 'SH' [3]

(E)erregcommon.c:1112,erRegGetAutoconnectFromMemory() theAutoconnect->backgroundConnectTo - Key file does not have key 'background_connect_to' [3]
(CL_W)control.c:432,ctrl_background_connect_timeout_start_withinterval() registry read: enable [0] interval [5]
Opening /dev/otgdev0 Try 1...Success
(CL_W)programManager.c:144,on_sigchld() entry: signo [17] pid [806] status [0x0000]
(CL_W)programManager.c:207,on_sigchld() end
Okay, that's pretty cool. What is this "Key file"? Any relation to key press signals?

Next, I moved to the "books" directory by pressing the "books" button, and navigated down a couple of subdirectories, all with button presses:

Code:
...
Nothing. Yup, no messages. Next, I opened a pdf file by selecting it in the contentLister:

Code:
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
(W)eripc.c:37,erIpcInitServer() Version: 256

(W)eripc.c:76,erIpcInitServer() Bound successfully to 127.0.0.1:50067.
(ERM_TRACE)ermanifest.c:95,LocateTo() LocateTo failed! no or empty xmlNodeSet
(ERM_TRACE)ermanifest.c:95,LocateTo() LocateTo failed! no or empty xmlNodeSet
(ERM_TRACE)ermanifest.c:95,LocateTo() LocateTo failed! no or empty xmlNodeSet
CPDFApp::loadScribble uses 45247
PDFDoc::displayPage 127 uses 891228

drawImage and XSync time 36792
PDFDoc::displayPage 128 uses 1348748
PDFDoc::displayPage 129 uses 876218
PDFDoc::displayPage 130 uses 891040
PDFDoc::displayPage 131 uses 759569
PDFDoc::displayPage 132 uses 836193
Clearly there's a window opening, then what appears to be some timing messages from iPDF giving how long different procedures take. The numbers are probably in milliseconds, suggesting that each page draw takes about 0.89 seconds on the average. I happen to know that after drawing the current page, iPDF draws and caches the next few pages immediately. Obviously, that's what's happening here.

The "PDFDoc::displayPage 131 uses 759569" messages are actually from iPDF, although they are obviously being passed along through the contentLister's output.

Let's turn the page backward:

Code:
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
PDFDoc::displayPage 126 uses 820161

drawImage and XSync time 34761
PDFDoc::displayPage 125 uses 955291
PDFDoc::displayPage 124 uses 612510
PDFDoc::displayPage 123 uses 425989
PDFDoc::displayPage 122 uses 793361
PDFDoc::displayPage 121 uses 885760
Yes, it caches a row of pages backwards. No mention of a keypress. Up arrow, down arrow, and dot presses give this:

Code:
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
Let's try quitting iPDF by pressing the 'escape' button, in the upper left corner of the iLiad:

Code:
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
(CL_E)programManager.c:448,pm_SendKey() NOT Sending keyrelease for UP key....
(CL_W)programManager.c:144,on_sigchld() entry: signo [17] pid [808] status [0x0000]
(CL_W)programManager.c:168,on_sigchld() last started [IPDF] pid [808]
(CL_W)programManager.c:207,on_sigchld() end
Okay, programManager.c has a function called pm_SendKey whose role clearly deals with keypresses, including whether to pass on key signals to other programs. It's worth noting that the escape (or "UP") key is a key that DOES get read by iPDF. So I launched iPDF again. Here's the output after I exited iPDF by pressing the "books" button (it's the same output for "news", "docs", "notes", or menu buttons):

Code:
(CL_E)programManager.c:887,pm_UpdateState() Failed to fetch class hint for window 0x200004
(CL_W)programManager.c:521,pm_TerminateUserApp() Terminate process [ipdf] pid [811]
On receive signal 15 pid 811
(CL_W)programManager.c:144,on_sigchld() entry: signo [17] pid [811] status [0x0000]
(CL_W)programManager.c:168,on_sigchld() last started [IPDF] pid [811]
(CL_W)programManager.c:207,on_sigchld() end
The function pm_SendKey isn't mentioned. Interesting.

Finally, here's a small experiment. I opened a pdf document using my modified iPDF which dumps keypresses to a log file. After testing it by turning pages (and reading the corresponding pagebar "keypresses" in the log), I killed the contentLister manually, then checked to be sure iPDF was still running:

Code:
# killall contentLister
# ps | grep ipdf
  820 root      14656 S   /usr/bin/ipdf /mnt/free/books/Doyle, Arthur Conan/Doyle - The Memoirs of Sherlock Holmes.pdf/Doyle - The Memoirs of Sherlock Holmes.pdf 
  821 root      14656 S   /usr/bin/ipdf /mnt/free/books/Doyle, Arthur Conan/Doyle - The Memoirs of Sherlock Holmes.pdf/Doyle - The Memoirs of Sherlock Holmes.pdf 
  822 root      14656 S   /usr/bin/ipdf /mnt/free/books/Doyle, Arthur Conan/Doyle - The Memoirs of Sherlock Holmes.pdf/Doyle - The Memoirs of Sherlock Holmes.pdf 
  833 root        448 S   grep ipdf
Then I tried turning pages in iPDF, and pushed every button I could find. No buttons worked at all, and the logfile registered no keypresses. The power switch also did not work.

Finally, I killed iPDF and restarted the contentLister again. Keys worked as before, and on sliding the power switch, I got this:

Code:
(CL_W)control.c:3293,ctrl_shutdown() entry

** (contentLister:850): CRITICAL **: ctrl_hide_pincode_screen: assertion `g_listerState == STATE_PINCODE' failed

Broadcast message from root (pts/0) (Mon Apr 12 14:12:20 1954):

The system is going down for system halt NOW!
(CL_W)control.c:3317,ctrl_shutdown() end
From the above experiments, I conclude that the "contentLister" is not just a simple content lister. It actually plays a key role in orchestrating many of the iLiad's functions. Notably, the contentLister seems responsible for reading and processing all button input.

One interesting message from the contentLister's start sequence is "Opening /dev/otgdev0 Try 1...Success". My guess would be that one of iRex's binary kernel drivers translates button interrupts into keypress data and dumps it to /dev/otgdev0. Then the contentLister takes that data from /dev/otgdev0 and forwards button press codes to window applications as necessary.

Bear in mind that this might be completely wrong. My interpretation and understanding of these experiments may be flawed. As I understand it, the conventional approach to X is that normally an X keyboard driver does the work of reading keyboard data and passing it along to the window manager. I have not yet read the iRex patches to the kernel and the xserver, and one of them may deal with button presses.

Comments, questions, suggestions, corrections, etc....?
jharker is offline   Reply With Quote