Last active
August 29, 2015 14:06
-
-
Save Noitidart/5a24e8a4f8886ce7bbf6 to your computer and use it in GitHub Desktop.
_ff-addon-snippet-X11_WindowsMatchingPid - Itterates through windows getting PIDs of them and returns windows found with specific PID. (js-ctypes) (X11)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Cu.import('resource://gre/modules/ctypes.jsm'); | |
function doit() { | |
try { | |
_x11 = ctypes.open('libX11.so.6'); | |
} catch (e) { | |
try { | |
var libName = ctypes.libraryName('X11'); | |
} catch (e) { | |
_x11 = false; | |
console.error('Integration: Could not get libX11 name; not activating'); | |
return; | |
} | |
try { | |
_x11 = ctypes.open(libName); | |
} catch (e) { | |
_x11 = false; | |
console.error('Integration: Could not open ' + libName + '; not activating'); | |
return; | |
} | |
} | |
//start - type constants | |
X11Atom = ctypes.unsigned_long; | |
X11Bool = ctypes.int; | |
X11Display = new ctypes.StructType('Display'); | |
X11Window = ctypes.unsigned_long; | |
X11Status = ctypes.int; | |
//end - type constants | |
//start - constants | |
var XA_CARDINAL = 6; //https://github.com/foudfou/FireTray/blob/d0c49867ea7cb815647bf13f2f1edb26439506ff/src/modules/ctypes/linux/x11.jsm#L117 | |
var None = 0; //https://github.com/foudfou/FireTray/blob/d0c49867ea7cb815647bf13f2f1edb26439506ff/src/modules/ctypes/linux/x11.jsm#L63 | |
var Success = 0; | |
//end - constants | |
/* | |
* Status XQueryTree( | |
* Display* display, | |
* Window w, | |
* Window* root_return, | |
* Window* parent_return, | |
* Window** children_return, | |
* unsigned int* nchildren_return | |
* ); | |
*/ | |
XQueryTree = _x11.declare('XQueryTree', ctypes.default_abi, X11Status, | |
X11Display.ptr, X11Window, X11Window.ptr, X11Window.ptr, X11Window.ptr.ptr, | |
ctypes.unsigned_int.ptr); | |
/* | |
* int XFree( | |
* void* data | |
* ); | |
*/ | |
XFree = _x11.declare('XFree', ctypes.default_abi, ctypes.int, ctypes.voidptr_t); | |
/* | |
* Display *XOpenDisplay( | |
* _Xconst char* display_name | |
* ); | |
*/ | |
XOpenDisplay = _x11.declare('XOpenDisplay', ctypes.default_abi, X11Display.ptr, | |
ctypes.char.ptr); | |
/* | |
* int XCloseDisplay( | |
* Display* display | |
* ); | |
*/ | |
XCloseDisplay = _x11.declare('XCloseDisplay', ctypes.default_abi, ctypes.int, | |
X11Display.ptr); | |
/* | |
* Window XDefaultRootWindow( | |
* Display* display | |
* ); | |
*/ | |
XDefaultRootWindow = _x11.declare('XDefaultRootWindow', ctypes.default_abi, | |
X11Window, X11Display.ptr); | |
/* | |
* Atom XInternAtom( | |
* Display* display, | |
* _Xconst char* atom_name, | |
* Bool only_if_exists | |
* ); | |
*/ | |
XInternAtom = _x11.declare('XInternAtom', ctypes.default_abi, X11Atom, | |
X11Display.ptr, ctypes.char.ptr, X11Bool); | |
/* | |
* extern int XGetWindowProperty( | |
* Display* display, | |
* Window w, | |
* Atom property, | |
* long long_offset, | |
* long long_length, | |
* Bool delete, | |
* Atom req_type, | |
* Atom* actual_type_return, | |
* int* actual_format_return, | |
* unsigned long* nitems_return, | |
* unsigned long* bytes_after_return, | |
* unsigned char** prop_return | |
* ); | |
*/ | |
XGetWindowProperty = _x11.declare('XGetWindowProperty', ctypes.default_abi, | |
ctypes.int, X11Display.ptr, X11Window, X11Atom, ctypes.long, ctypes.long, | |
X11Bool, X11Atom, X11Atom.ptr, ctypes.int.ptr, ctypes.unsigned_long.ptr, | |
ctypes.unsigned_long.ptr, ctypes.char.ptr.ptr); | |
//////////////////////// | |
////END DECLARATIONS | |
//////////////////////// | |
var _x11Display = XOpenDisplay(null); | |
if (!_x11Display) { | |
console.error('Integration: Could not open display; not activating'); | |
_x11 = false; | |
return; | |
} | |
var _x11RootWindow = XDefaultRootWindow(_x11Display); | |
if (!_x11RootWindow) { | |
console.error('Integration: Could not get root window; not activating'); | |
_x11 = false; | |
return; | |
} | |
//start - WindowsMatchingPid from http://stackoverflow.com/questions/151407/how-to-get-an-x11-window-from-a-process-id | |
//start - searchForPidStartingAtWindow func | |
var _atomPIDInited = false; | |
var _atomPID; | |
var _matchingWins = []; | |
function searchForPidStartingAtWindow(w, _disp, targetPid, isRecurse) { // when you call must always leave isRecurse null or false, its only used by the function to identify when to clear out _matchingWins | |
if (!isRecurse) { | |
//user just called this function so clear _matchingWins | |
_matchingWins = []; | |
} | |
//console.log('h1'); | |
//make sure to clear _matchingWins arr before running this | |
if (!_atomPIDInited) { | |
_atomPID = XInternAtom(_disp, '_NET_WM_PID', true); | |
console.log('_atomPID:', _atomPID, _atomPID.toString(), parseInt(_atomPID)); | |
if(_atomPID == None) { | |
console.error('No such atom ("_NET_WM_PID"), _atomPID:', _atomPID); | |
throw new Error('No such atom ("_NET_WM_PID"), _atomPID:' + _atomPID); | |
} | |
_atomPIDInited = true; | |
} | |
var returnType = new X11Atom(), | |
returnFormat = new ctypes.int(), | |
nItemsReturned = new ctypes.unsigned_long(), | |
nBytesAfterReturn = new ctypes.unsigned_long(), | |
propData = new ctypes.char.ptr(); | |
//console.log('h2'); | |
//console.log('_disp:', _disp, 'w:', w, '_atomPID:', _atomPID); | |
var rez = XGetWindowProperty(_disp, w, _atomPID, 0, 1024, false, XA_CARDINAL, returnType.address(), returnFormat.address(), nItemsReturned.address(), nBytesAfterReturn.address(), propData.address()); | |
//console.log('h3'); | |
/* | |
if (isRecurse) { | |
console.log('isRecurse so return b1'); | |
return; | |
} | |
*/ | |
//console.log('XGetWindowProperty', 'rez:', rez, 'returnType:', returnType, 'nItemsReturned:', nItemsReturned, 'nBytesAfterReturn:', nBytesAfterReturn, 'propData:', propData); | |
if (rez == Success) { | |
var nElements = ctypes.cast(nItemsReturned, ctypes.unsigned_int).value; | |
if(nElements) { | |
//var rezArr = [propData, nElements]; | |
console.log('nElements > 0:', nElements, '(should always be one, as per window should have only one pid, but its an array so lets loop through just to make sure)'); | |
if (nElements > 1) { | |
throw new Error('how on earth??? nElements is > 1, windows should only have one pid...', 'nElements:', nElements); | |
} | |
//var clientList = ctypes.cast(res[0], X11Window.array(nClients).ptr).contents, | |
var pidList = ctypes.cast(propData, ctypes.unsigned_long.array(nElements).ptr).contents; | |
for (var i=0; i<nElements; i++) { | |
var pid = pidList.addressOfElement(i).contents; | |
console.log('pid:', pid); | |
//if (pid == targetPid) { | |
if (ctypes.UInt64.compare(pid, ctypes.UInt64(targetPid)) == 0) { //if == 0 then they are equal | |
console.log('pid match at', pid.toString(), targetPid); | |
_matchingWins.push(w); | |
} | |
} | |
//var rez = XFree(propData); //i dont know if i should xfree anything | |
//console.log('rez of XFree on propData:', rez); | |
} else { | |
console.log('no elements, nElements:', nElements, 'THUS meaning no pid on this window'); | |
} | |
} else { | |
console.error('failed on XGetWindowProperty, rez:', rez); | |
} | |
/* | |
if (isRecurse) { | |
console.log('isRecurse so return'); | |
return; | |
} | |
*/ | |
//console.log('recurse into'); | |
// recurse into child windows | |
var wRoot = new X11Window(); | |
var wParent = new X11Window(); | |
var wChild = new X11Window.ptr(); | |
var nChildren = new ctypes.unsigned_int(); | |
var rez = XQueryTree(_disp, w, wRoot.address(), wParent.address(), wChild.address(), nChildren.address()); | |
if(rez != 0) { //can probably test this against `None` instead of `0` | |
var nChildrenCasted = ctypes.cast(nChildren, ctypes.unsigned_int).value; | |
console.log('nChildrenCasted:', nChildrenCasted); | |
if (nChildrenCasted > 0) { | |
var wChildCasted = ctypes.cast(wChild, X11Window.array(nChildrenCasted).ptr).contents; //SAME AS: `var wChildCasted = ctypes.cast(wChild, ctypes.ArrayType(X11Window, nChildrenCasted).ptr).contents;` | |
for(var i=0; i<wChildCasted.length; i++) { | |
var wChildElementCasted = wChildCasted.addressOfElement(i).contents; //DO NOT DO `var wChildElementCasted = ctypes.cast(wChildCasted.addressOfElement(i), X11Window).value;`, it crashes on line 234 when passing as `w` into `XGetWindowProperty` | |
//console.log('wChildElementCasted:', wChildElementCasted, 'w:', w); | |
searchForPidStartingAtWindow(wChildElementCasted, _disp, targetPid, true); | |
} | |
} else { | |
console.log('this window has no children, nChildrenCasted:', nChildrenCasted); | |
} | |
} else { | |
console.warn('XQueryTree failed:', rez); | |
} | |
return _matchingWins; | |
} | |
//end - searchForPidStartingAtWindow func | |
var wins = searchForPidStartingAtWindow(_x11RootWindow, _x11Display, 4398); //dont pass isRecurse here, important, otherwise if use this func multiple times, you'll have left over windows in the returned array from a previous run of this func | |
console.log('wins:', wins); | |
//end - WindowsMatchingPid | |
XCloseDisplay(_x11Display); | |
//_X11BringToForeground(win, intervalID); | |
} | |
doit(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
README
ctypes
X11 skeleton jacked from GitHub :: zotero / zotero - integration.js L#365Rev1
prop_value.address()
toXGetWindowProperty
on L#221, I can't figure it out, I did it exactly like the place I'm copying from does it: GitHub :: foudfou / FireTray - FiretrayWindow.jsm L#421It keeps throwing this error:
Rev2
Fixed the rev 1 L221 error with using the code from where I jacked the x11 framework, so from here: GitHub :: zotero / zotero - integration.js L#571
Setup recurse child beginnings
Rev3
searchForPidStartAtWindow
Rev4
wChild[i]
tosearchForPidStartAtWindow
to recursedebugSingleRecurse
thing to make sure it only recurses once i should remove thisRev5
Got
wChild[i]
passing intosearchForPidStartAtWindow
however its coming into some errorRev6
casted
wChild
right toArrayType
however I was casting again the element, and this was crashing on line 234 when passing asw
intoXGetWindowProperty
Rev7
pid
totargetPid
to properly usectypes.UInt.compare
even though it seemedpid == 4398
was working, I don't know if its the right thing to do.Rev8
WindowsMatchingPid
so it matches from the SO topicRev9
XFree
as I think I need to use that, I'm just not sure how yet, I think I know where, it's just I didn't see an affect so I didn't use it, but commented out in previous revs