void MainWindow::push_char(char character)
{
Display * disp; //current X11 display
disp=XOpenDisplay(nullptr); //TODO: fail gracefully when abused in console.
KeySym * xkeysyms = nullptr;
int temporaryKeyCode=0;
int keycodes_start=0;
int keycodes_end=0;
int keysyms_per_keycode=0;
XDisplayKeycodes(disp,&keycodes_start,&keycodes_end); //obtain keycode range for current display.
xkeysyms=XGetKeyboardMapping(disp,keycodes_start,keycodes_end-keycodes_start,&keysyms_per_keycode); //get keysyms start-end
for (int i=keycodes_start; i<=keycodes_end; i++) //Iterate through keycode list to obtain free one
{
bool empty_keycode=true;
for (int j=0; j<keysyms_per_keycode; j++) //check all keysyms to be zero
{
int keysym_index = (i - keycodes_start) * keysyms_per_keycode + j; //obtain keysym position
if(xkeysyms[keysym_index] != 0) //if the key is not empty...
{
empty_keycode=false; //nope... next one
break;
}
}
if (empty_keycode) //use this code for our character.
{
temporaryKeyCode=i;
break;
}
}
XFree(xkeysyms); //this finding and freeing must be done every time, not at the program boot-up,
XFlush(disp); //as user may change X settings on the fly, including key tables.
usleep(100*1000); //0.1 delay
//Prepare for character send
KeySym sym = XStringToKeysym("U01F92A"); //Uxxxx links unknown UTF char to key even when it's not in any definition. As in xkbcommon-keysyms.h
// KeySym sym = XStringToKeysym("U0142"); //THIS WORKS., the above does not in all applications.
if (sym == NoSymbol) //This should rarely happen.
{
sym=XStringToKeysym("x"); //have anything here or throw error.
}
KeySym symlist[2]={sym, sym}; //create a keysym list for shifted and unshifted chr
XChangeKeyboardMapping(disp,temporaryKeyCode,2,symlist,1); //assign the list to the mapping
XFlush(disp);
KeyCode code=temporaryKeyCode; //create code out of temporary
XTestFakeKeyEvent(disp, code, true, 0); //Press...
XFlush(disp);
usleep(90 * 1000);
XTestFakeKeyEvent(disp, code, false, 0); //Release...
XFlush(disp);
symlist[0]=0;
symlist[1]=0;
XChangeKeyboardMapping(disp,temporaryKeyCode,2,symlist,1); //revert the mapping
usleep(90 * 1000);
XCloseDisplay(disp); //End routine
return;
}
void MainWindow::push_char(char character)
{
Display * disp; //current X11 display
disp=XOpenDisplay(nullptr); //TODO: fail gracefully when abused in console.
KeySym * xkeysyms = nullptr;
int temporaryKeyCode=0;
int keycodes_start=0;
int keycodes_end=0;
int keysyms_per_keycode=0;
XDisplayKeycodes(disp,&keycodes_start,&keycodes_end); //obtain keycode range for current display.
xkeysyms=XGetKeyboardMapping(disp,keycodes_start,keycodes_end-keycodes_start,&keysyms_per_keycode); //get keysyms start-end
for (int i=keycodes_start; i<=keycodes_end; i++) //Iterate through keycode list to obtain free one
{
bool empty_keycode=true;
for (int j=0; j<keysyms_per_keycode; j++) //check all keysyms to be zero
{
int keysym_index = (i - keycodes_start) * keysyms_per_keycode + j; //obtain keysym position
if(xkeysyms[keysym_index] != 0) //if the key is not empty...
{
empty_keycode=false; //nope... next one
break;
}
}
if (empty_keycode) //use this code for our character.
{
temporaryKeyCode=i;
break;
}
}
XFree(xkeysyms); //this finding and freeing must be done every time, not at the program boot-up,
XFlush(disp); //as user may change X settings on the fly, including key tables.
usleep(100*1000); //0.1 delay
//Prepare for character send
KeySym sym = XStringToKeysym("U01F92A"); //Uxxxx links unknown UTF char to key even when it's not in any definition. As in xkbcommon-keysyms.h
// KeySym sym = XStringToKeysym("U0142"); //THIS WORKS., the above does not in all applications.
if (sym == NoSymbol) //This should rarely happen.
{
sym=XStringToKeysym("x"); //have anything here or throw error.
}
KeySym symlist[2]={sym, sym}; //create a keysym list for shifted and unshifted chr
XChangeKeyboardMapping(disp,temporaryKeyCode,2,symlist,1); //assign the list to the mapping
XFlush(disp);
KeyCode code=temporaryKeyCode; //create code out of temporary
XTestFakeKeyEvent(disp, code, true, 0); //Press...
XFlush(disp);
usleep(90 * 1000);
XTestFakeKeyEvent(disp, code, false, 0); //Release...
XFlush(disp);
symlist[0]=0;
symlist[1]=0;
XChangeKeyboardMapping(disp,temporaryKeyCode,2,symlist,1); //revert the mapping
usleep(90 * 1000);
XCloseDisplay(disp); //End routine
return;
}
To copy to clipboard, switch view to plain text mode
Bookmarks