![]() |
#1 |
Junior Member
![]() Posts: 5
Karma: 10
Join Date: Sep 2007
Device: Neo1973
|
Access the hardware keys
Hi,
I am new to Iliad development. ![]() I want to receive events when someone presses any of the hardware keys of the iliad. Can you tell me how that can be done? Can I even get keyboard events when my app is not the focused one? If so, how? ![]() Regards |
![]() |
![]() |
![]() |
#2 |
Developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 345
Karma: 3473
Join Date: Apr 2007
Location: Brooklyn, NY, USA
Device: iRex iLiad v1, Blackberry Tour, Kindle DX, iPad.
|
Actually, I've studied this question in great detail. It's much more complicated than you might think. I started a thread about it over at the iRex forum, but I never posted detailed information about it. For the interested, here's a summary.
The iLiad buttons can be grouped into two categories. Yes, the power switch is considered a "button".
Instead, the ContentLister program runs in the background all the time and constantly queries the hardware buttons at /dev/buttons directly using ioctls. When a button is pressed, the ContentLister decides whether it was a "long press" or a "short press" and what to do with it. If it's a "normal" button, the ContentLister sends a key press event to the X server. (Matthijs informed me that XSendEvent is used for this, thanks, Matthijs!) If it's a "special" button, the ContentLister never passes it to the X server at all. More on this later. You can easily use any of the "normal" buttons you want, simply by getting them through the X server. Here's how the "normal" buttons are represented as key presses in X via GDK: Code:
Button Press Keypress Equivalent
============ ===================
Up Arrow GDK_Up
Dot (Enter) GDK_Return
Down Arrow GDK_Down
Long Up Arrow GDK_F4
Long Dot (Enter) GDK_F6
Long Down Arrow GDK_F3
Page Forward GDK_Page_Down
Page Back GDK_Page_Up
Long Page Forward GDK_F1
Long Page Back GDK_F2
Escape GDK_F5
So, there's no way to read any of the "special" buttons without writing your own program to query the button driver directly, the same way the ContentLister does. Now, you can have a second program query the button driver simultaneously with the ContentLister. I've written such a program and it works beautifully. However, there's a small problem: if a button press is short enough (less than 1/10 second), it's possible for your program to catch the button push and the ContentLister to miss it (or vice versa). This is because querying the button data resets it, so if you push quick enough, one program will read the button data, and by the time the other program queries the driver, you've released the button and there's no data to get. If anyone's interested in the gritty details of the button driver, ioctls, button handling, etc., I'd be happy to provide them. I have a short program that queries the iLiad buttons directly, as well as a reference of the hex code that each button returns. If you're interested, let me know! Hope this helps! |
![]() |
![]() |
![]() |
#3 |
Junior Member
![]() Posts: 5
Karma: 10
Join Date: Sep 2007
Device: Neo1973
|
Hi. Thanks for all the information!!!
I would be very happy to receive any source code that show how /dev/buttons can be read. You can send it to: thebohemian (at) gmx.net Regards Robert |
![]() |
![]() |
![]() |
#4 |
Junior Member
![]() Posts: 6
Karma: 10
Join Date: Nov 2007
Device: Iliad
|
Yes please, sample of both way would be very welcome.
I'm trying to catch "GDK" buttons in a pygtk program but it doesn't seems to get them ![]() |
![]() |
![]() |
![]() |
#5 |
Junior Member
![]() Posts: 8
Karma: 10
Join Date: Nov 2007
Device: iLiad
|
I too would like to see your sources
![]() |
![]() |
![]() |
![]() |
#6 |
Developer
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 345
Karma: 3473
Join Date: Apr 2007
Location: Brooklyn, NY, USA
Device: iRex iLiad v1, Blackberry Tour, Kindle DX, iPad.
|
How to access the iLiad's hardware buttons directly
Okay, by popular demand, here's a simple command-line program to let you query the iLiad's hardware buttons directly!
ButtonReader-1.0.tar.gz - This archive contains the source code, a precompiled binary, and a README with some notes on how it all works. The source code is distributed under the GNU GPL v3. For those who are interested, here's the source code of the program for perusal and discussion: Code:
/*********************************************************** * ButtonReader-1.0.c * * This is a simple program to read button presses on the iRex iLiad. * It may be run from the command line. When a button is pressed, it * prints a line to stdout stating which button was pressed. * * This program is Copyright 2007 by John C. Harker, who may be reached * via email at John.C.Harker <at> gmail.com. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Typically a copy of the GNU General Public License is located in the * file named COPYING. * ***********************************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <time.h> #define SLEEPTIME_NSEC 100000000 int main(void) { unsigned int data; int i,j; int fd_buttons; int loop = 1; struct timespec sleeptime; sleeptime.tv_sec = (time_t) 0; sleeptime.tv_nsec = SLEEPTIME_NSEC; fd_buttons = open( "/dev/buttons", O_RDWR ); if ( fd_buttons < 0 ) { printf("Could not open /dev/buttons.\n"); exit(1); } while ( loop == 1 ) { nanosleep(&sleeptime, NULL); // Clear the data variable data = 0; // Request any data ioctl(fd_buttons, 0x80046207, &data); // Print out the data switch( data ) { case 0x00000800: printf("iDS Connect"); break; case 0x00000801: printf("Options"); break; case 0x00000802: printf("Escape (level up)"); loop = 0; break; case 0x00000803: printf("News"); break; case 0x00000804: printf("Books"); break; case 0x00000805: printf("Docs"); break; case 0x00000806: printf("Notes"); break; case 0x00000807: printf("Pagebar Left"); break; case 0x00000808: printf("Pagebar Right"); break; case 0x00000809: printf("Up Arrow"); break; case 0x0000080a: printf("Dot (Enter)"); break; case 0x0000080b: printf("Down Arrow"); break; case 0x0000080e: printf("Power"); break; case 0x000008ff: /* no button pressed */ break; default: printf("***Unknown code 0x%08x ***", data); break; } if ( data != 0x000008ff ) { printf(" button pressed!\n"); } } /* end of button-reading do loop */ printf("Halted!\n"); close(fd_buttons); return 0; } The ioctl polling method is somewhat inconvenient because it means that the program must be constantly polling in order to read button presses. If we could rewrite the actual kernel driver we might be able to change this... but figuring out how THAT works would be even harder. Still, this is cool stuff. I hope someone finds it useful! Last edited by jharker; 11-05-2007 at 03:53 PM. Reason: Minor wording changes. |
![]() |
![]() |
![]() |
#7 |
fruminous edugeek
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Posts: 6,745
Karma: 551260
Join Date: Oct 2006
Location: Northeast US
Device: iPad, eBw 1150
|
I was just thinking yesterday that I'd like to see IDS Connect reconfigured so that if you are in an application, rather than in ContentLister, it would cycle between open applications (and a task launching application).
Then I could be reading a PDF or something in FBReader and flipping over to a Notes page and back as needed. |
![]() |
![]() |
![]() |
#8 |
Junior Member
![]() Posts: 6
Karma: 10
Join Date: Nov 2007
Device: Iliad
|
Many thanks for the sample. It's indeed easier than I thought. But how frequently do you need to poll /dev/buttons ? I guess I'll test that.
|
![]() |
![]() |
![]() |
#9 |
Junior Member
![]() Posts: 6
Karma: 10
Join Date: Nov 2007
Device: Iliad
|
|
![]() |
![]() |
![]() |
#10 |
Guru
![]() ![]() ![]() ![]() ![]() ![]() Posts: 976
Karma: 687
Join Date: Nov 2007
Device: Dell X51v; iLiad v2
|
I am porting some Qt app right now. Basically, the app (with Qt4.5.2) is running on my iLiad right now (Thanx to xepdmgr). Although I can control LED flash through ERIPC, the major problem I am facing is that I can't use page-flip bar. GTK+ apps can receive GdkKeyEvent without any problem, but it seems quite tough for Qt apps.
In my Qt app, page-up and page-down key should trigger some actions if receiving proper key-events, but in fact, on my iLiad, nothing happened when I flip the pagebar. So I guess Qt didn't receive proper signal from X. I don't know how to do it. Do you have any better ideas? ![]() Last edited by ericshliao; 07-05-2009 at 10:53 PM. |
![]() |
![]() |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
SSH keys with dropbear? | enn | Kindle Developer's Corner | 2 | 10-07-2010 12:54 AM |
Kobo Firmware Access and Early Access Program | PeterT | Kobo Reader | 115 | 08-09-2010 08:06 PM |
SCI-FI: Daniel Keys Moran | ekaser | Reading Recommendations | 2 | 09-11-2009 01:19 AM |
what is wrong with these keys | KingDani | iRex | 8 | 05-06-2009 11:42 PM |
Use keys in Mobipocket | ddavtian | iRex | 0 | 10-14-2007 04:03 PM |