Order it now! Amazon prioritizes orders on a first come, first served basis.


View Full Version : non-GTK+ apps not getting button event from X


ericshliao
08-20-2009, 12:35 AM
Based on my current experience, all GTK+ apps can respond to iLiad buttons without any problem. But I found that I can't make QT based app (djview4) and wxWidgets based app (xCHM) respond to iLiad button, even though I can control iLiad led flash and use touch-pen as mouse in these apps.

My current understanding is:
Contentlister will grab all iLiad button-events by calling button driver. Then, a button-event will be translated to an X event and transferred to the foreground x-client using the following function in programManager.c:
void pm_SendKey(KeySym keysym)
{
XKeyEvent xev;
Display *display;
Window window, root;
int screen;

display = gdk_x11_display_get_xdisplay(gdk_display_get_defau lt());
root = gdk_x11_get_default_root_xwindow();
window = pm_getWinOnTop();
if (window == -1)
{
CL_ERRORPRINTF("Failed: no valid window found");
return;
}

if (window == g_myWin)
{
CL_PMPRINTF("ContentLister window 0x%x", (unsigned int)window);

display = XOpenDisplay(NULL);
screen = DefaultScreen(display);
root = RootWindow(display, screen);
}

// create and send a keypress event followed by a keyrelease event
xev.type = KeyPress;
xev.display = display;
xev.root = root;
xev.window = window;
xev.subwindow = None;
xev.time = pm_fake_timestamp();
xev.x = 1;
xev.y = 1;
xev.x_root = 1;
xev.y_root = 1;
xev.same_screen = 1;
xev.state = 0;
xev.keycode = XKeysymToKeycode(display, keysym);
// CL_ERRORPRINTF("Sending keypress....");
XSendEvent(xev.display, window, 1, KeyPressMask, (XEvent *) & xev);

// We check to see if this is the UP key
// so we don't send the release event for that, because it
// can crash the contentLister with a BadWindow error (req.code 25)
if ( keysym == GDK_F5 )
{
CL_ERRORPRINTF("NOT Sending keyrelease for UP key....");
}
else
{
// usleep(2000); // MvdW: this usleep doesn't seem to be nescessary
xev.type = KeyRelease;
xev.time = pm_fake_timestamp();
XSendEvent(xev.display, window, 1, KeyReleaseMask, (XEvent *) & xev);
}

//XSync(xev.display, 1);
XSync(xev.display, FALSE);

if (window == g_myWin)
{
CL_PMPRINTF("Before XCloseDisplay()");
XCloseDisplay(display);
}
}

I just can't figure out why do these x apps can't respond to iLiad button event. Does anybody have an idea how to solve or trace the problem?

Max
08-21-2009, 03:17 AM
As I understand, contentlister use the wmclass/name of the window to find it.

I don't know how to do it in QT based app and wxWidgets based app. Look this for more info:

http://www.mobileread.com/forums/showthread.php?t=21776&highlight=wmclass
http://forum.irexnet.com/viewtopic.php?t=1110

ericshliao
08-21-2009, 05:40 AM
Ah, I forgot to try this approach. Thanx for reminding me. I should not forget it.:smack:
I remembered that I tried to set it in djview4 but still got no response when pushing page-flip button. Maybe I didn't do it corretly. I will try again.

Max
08-21-2009, 05:45 AM
If you are launching the program from a shell script remember that the class and title of the windows should be sh.

ericshliao
08-21-2009, 08:46 PM
If you are launching the program from a shell script remember that the class and title of the windows should be sh.

Yes, I know this. Thanx. :thanks:
For GTK+ based app, I know how to set WM_CLASS, but for QT app, I don't find any proper funtion to do the task.:chinscratch:

hansel
08-30-2009, 12:44 AM
Hi,

Just back from holidays...

I know how to set WM_CLASS, but for QT app, I don't find any proper funtion to do the task.:chinscratch:

You can set/get it by calling Xlib functions directly

http://tronche.com/gui/x/xlib/ICC/client-to-window-manager/XSetClassHint.html

ericshliao
08-30-2009, 03:21 AM
:smack:Ha! Thanx. I've never thought of this approach.

ericshliao
08-30-2009, 06:52 AM
It's so great! This approach works.:2thumbsup
Now LED and buttons on iLiad can be used in QT4 apps.

I borrowed some code from trayicon_x11.cpp (http://www.codase.com/search/display?file=L2dlbnRvbzIvdmFyL3RtcC9yZXBvcy9jb2Rhc 2UuYy9rbXAtMC41L3dvcmsva21wL3RyYXlpY29uX3gxMS5jcHA =&lang=c%2B%2B&off=3822+3834+) and made some modification.

This is the code that I use in djview4 for iLiad:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <QX11Info>



Display *dsp = QX11Info::display();
WId leader = winId();
// set the class hint
XClassHint classhint;
classhint.res_name = (char*)"sh";
classhint.res_class = (char*)"sh";
XSetClassHint(dsp, leader, &classhint);
// set the Window Manager hints
XWMHints *hints;
hints = XGetWMHints(dsp, leader); // init hints
hints->flags = WindowGroupHint | IconWindowHint | StateHint; // set the window group hint
hints->window_group = leader; // set the window hint
hints->initial_state = WithdrawnState; // initial state
//hints->icon_window = icon; // in WM, this should be winId() of separate widget
hints->icon_x = 0;
hints->icon_y = 0;

XSetWMHints(dsp, leader, hints); // set the window hints for WM to use.
XFree( hints );
//end setting WM hints